Recibo do Exame de Introdução à Programação (IGE/ETI), 1º semestre de 2000/2001, ISCTE:

Nome do aluno: _______________________________________________

Número do aluno:  ______________________

Assinatura do docente: ________________________________________


Identificação

Nome do aluno: _______________________________________________

Número do aluno:  ______________________

Turma: ____________


Exame

Introdução à Programação

IGE e ETI

1º semestre de 2000/2001

ISCTE


Notas:


 

Questão 1

Assinale com V (Verdadeiro) as expressões que estão correctas e com F (Falso) as que estão incorrectas.

Deve preencher todos os espaços indicados por um sublinhado (___) com V ou F. Qualquer espaço não preenchido será considerado como uma resposta errada.

Em geral as alíneas podem ter zero ou mais respostas correctas.  Cada resposta correctamente assinalada vale 0,5 valores.

Nas alíneas em que apenas uma resposta está correcta (se existirem estão assinaladas no texto), responder com mais ou menos do que um V anula a cotação.  A resposta correcta corresponde à cotação completa.  Qualquer outra resposta corresponde a zero valores.

Em todos os casos em que não é explicitamente referida a localização de uma instrução, considere que esta é dada na função main() do programa seguinte:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class A {

  public:

    int z;

    A(int const, int const = 1);

    int f1();

    int f2();
    int f3(int);

  private:
    vector<int> x;
    int f4();
};

...

int main()

{
    int const i = 1;
    A meu_a(2, 3);
    A const outro_a(2, 3);
    vector<int> v(1);
    v[0] = 3;
    ...
}

1.1  Admita que qualquer uma destas instruções é dada na função main() no local indicado pelas reticências (...).  Quais das seguintes instruções estão correctas?

__  A a;
__  A a(2);
__  A a(v[0], v[0]);

[cotação: 1,5]

 

 

 

1.2  Admita que qualquer uma destas instruções é dada na função main() no local indicado pelas reticências (...). Quais das seguintes instruções estão correctas?

__ int c = meu_a.x[2];
__ i = meu_a.f4();
__ int k = outro_a.f1();
__ meu_a.z = outro_a.z;

[cotação: 2]

1.3  Assuma que as seguintes instruções são dadas dentro de uma função ou procedimento membro da classe A e que não são declaradas quaisquer variáveis ou constantes dentro dessa função ou procedimento (que não tem quaisquer parâmetros).  Quais das seguintes instruções estão correctas?

__  v[0] = 1;
__  x[0] = f3();

[cotação: 1]

1.4  Suponha as seguintes definições dos métodos acima declarados:

A::A(int const i, int const n)
    : x(n), z(i) 
{
}

void A::f2()
{

    for(vector<int>::size_type i = 0; i != x.size(); ++i)
        x[i] = z;
}

int A::f3(int const i) 
{

    return x[i];
}

int main() 
{

    A a(4, 5);
    cout << a.f3(2);
    a.f2();
    cout << ' ' << a.f3(3) << endl;
}

Assumindo que os restantes métodos da classe estão definidos, qual é o resultado da invocação do programa?
Apenas uma das opções está correcta.

__   5 4
__   0 5
__   0 4
__   5 0

[cotação: 0,5]

 

 

 

Questão 2

Considere o problema da gestão dos navios que atracam no Porto de Lisboa para cargas e descargas.  Quando chega, um navio pede autorização para atracar, enviando para isso a sua informação (nome e matrícula) a um dos controladores do Porto de Lisboa.  Nesse momento é-lhe atribuído um cais livre (existem 10 cais de carga/descarga de mercadorias, numerados de 1 a 10, cada um dos quais suporta apenas um navio).  Caso não exista um cais disponível, o navio é colocado em fila de espera até que um dos cais seja libertado.  A fila de espera tem um limite de 50 navios (os que cabem no Mar da Palha).  Logo que um cais esteja disponível, o navio é autorizado a atracar e proceder à carga e descarga das mercadorias.  Quando termina a operação, o navio envia um aviso a um dos controladores do Porto de Lisboa indicando que  libertou o cais que lhe estava atribuído, o que poderá permitir a atracação de um navio em espera.  Pretende-se construir e testar uma parte do sistema de controlo do Porto de Lisboa.

2.1  Defina a classe RegistoDeNavio de modo a guardar:

  1. O nome do navio.  Uma cadeia de caracteres sem espaços.
  2. A matrícula do navio.  Uma cadeia de caracteres sem espaços.
  3. O número do cais onde está a carregar/descarregar mercadoria.  Caso o navio não esteja em nenhum cais o valor desta variável deverá ser zero (0).
A classe RegistoDeNavio deve dispor dos seguintes métodos:

Indique claramente quais dos métodos da classe não alteram a instância implícita.

Não é necessário nesta questão definir qualquer um dos métodos (funções ou procedimentos membro) da classe.

A interface desta classe é fundamental para as alíneas seguintes!

[cotação: 1]
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Em cada uma das alíneas seguintes considere como completa a resolução das alíneas anteriores, mesmo que a não tenha realizado.

2.2  Considere a seguinte classe:

class ConjuntoDeRegistosDeNavios {
 
  public:
    ConjuntoDeRegistosDeNavios();

    RegistoDeNavio registoDeNavioComMatrícula(string const& matrícula) const;

    bool contémRegistoDeNavioComMatrícula(string const& matrícula) const;

    void mostra() const;

    void insere(RegistoDeNavio const& registo_de_navio);
    void removeRegistoDeNavioComMatrícula(string const& matrícula);

  private:


 

 








};

Esta classe representa conjuntos de registos de navios (sem limite quanto ao número de registos):

 Complete parcialmente a classe definindo as suas variáveis privadas (use o espaço na definição da classe) e definindo os seguintes métodos:

Coloque asserções verificando as pré-condições nos métodos definidos.

[cotação: 2]
 


 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 
 
 
 
 
 

2.3  Considere a seguinte classe:

class FilaDeRegistosDeNavios {
 
  public:
    FilaDeRegistosDeNavios();

    RegistoDeNavio primeiro() const;

    bool contémRegistoDeNavioComMatrícula(string const& matrícula) const;

    bool vazia() const;
    bool cheia() const;

    void mostra() const;

    int comprimento() const;

    void põe(RegistoDeNavio const& registo_de_navio);
    void tira();

  private:


 

 




};

Esta classe representa filas de espera de registos de navios com um máximo de 50 registos.  Numa fila de espera o primeiro item a entrar é o primeiro a sair:

 Complete parcialmente a classe definindo as suas variáveis privadas (use o espaço na definição da classe) e definindo os seguintes métodos:

Coloque asserções verificando as pré-condições nos métodos definidos.

[cotação: 2]
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 
 
 

 

 

 

 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 
 
 

 

 

 

 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

2.4  Defina a classe ControladorDoPorto que representa e controla o estado do porto em cada instante de tempo.  Deve incluir os métodos necessários para:

  1. Construir uma nova variável do tipo ControladorDoPorto dado o número de cais do porto em questão (e.g. 10).
  2. Registar a chegada de um navio (sendo a informação sobre o navio dada como argumento na forma de um registo de navio).  Admite-se que a matrícula do navio chegado é diferente de todos os outros navios em causa, incluindo os que estão nos cais e os que estão em espera (pré-condição).  Se houver lugar num cais, o navio é autorizado a atracar nele.  Se não houver lugar, o navio deve ficar em espera.  Se não houver espaço para o navio esperar, nada deve acontecer (ou seja, o navio é mandado embora).
  3. Registar a partida de um navio que se encontrava num cais (recebe a  matrícula do navio que está de partida).  Admite-se que existe um navio num cais com a matrícula dada (pré-condição).  Se existirem navios em espera, o primeiro da fila tem ordem para entrar no porto e atracar no cais que foi libertado.
  4. Verificar se há algum cais disponível ou não.
  5. Verificar se há espaço no porto, quer em algum cais quer na fila de espera.
  6. Devolver o número de navios na fila de espera.
  7. Mostrar todos os navios na fila de espera.
  8. Mostrar todos os navios que se encontram atracados.
  9. Verificar se um navio com uma matrícula dada se encontra atracado.
  10. Verificar se um navio com uma matrícula dada se encontra na fila à espera de atracar.

Indique claramente quais dos métodos da classe não alteram a instância implícita.

Faça uso das classes FilaDeRegistosDeNavios e ConjuntoDeRegistosDeNavio para guardar os navios em espera e os navios atracados, respectivamente.

Não é necessário nesta questão definir qualquer um dos métodos.  Coloque comentários indicando claramente para que serve cada uma das variáveis membro que definir.

[cotação: 2]
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

2.5  Defina os seguintes métodos da classe ControladorDoPorto:

  1. Construir uma nova variável do tipo ControladorDoPorto dado o número de cais do porto em questão (e.g. 10).
  2. Registar a partida de um navio que se encontrava num cais (recebe a  matrícula do navio que está de partida).  Admite-se que existe um navio num cais com a matrícula dada (pré-condição).  Se existirem navios em espera, o primeiro da fila tem ordem para entrar no porto e atracar no cais que foi libertado.
  3. Verificar se um navio com uma matrícula dada se encontra atracado.

[cotação: 2]
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 
 
 
 

 

 

 


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 
 
 

2.6  Escreva um programa que simule o funcionamento do Porto de Lisboa.  Admita que no início não existem navios atracados ou em fila de espera.  O programa deve mostrar ao utilizador um menu que permita as seguintes operações:

  1. Registar a chegada de um navio.  Deve pedir ao utilizador para inserir toda a informação sobre um navio e registar a entrada desse navio.  Se a matrícula já existir quer em algum cais quer em espera, deve simplesmente avisar o utilizador.  Caso não haja lugar nem em cais nem em fila, deve simplesmente avisar o utilizador.
  2. Registar a partida de um navio de um cais.  Deve pedir ao utilizador a matrícula do navio a retirar (o que tem como consequência a atracagem do primeiro navio em espera, se existir algum).  Se não houver nenhum barco com a matrícula indicada, deve simplesmente avisar o utilizador.
  3. Mostrar todos os navios que se encontram atracados e em fila de espera.

O programa não deve abortar em caso algum.  Pode, se quiser, definir funções ou procedimentos que ache necessários para modularizar o programa.

Exemplo de interacção:

Controlador do Porto De Lisboa

1. Registar entrada
2. Registar partida
3. Mostrar situação do porto
Opção: 1

Qual o nome do navio? Maria_das_Ondas
Qual a matrícula? 123sq45

Navio registado.  Atracagem permitida.

... várias horas depois ... 

Controlador do Porto De Lisboa

1. Registar entrada
2. Registar partida
3. Mostrar situação do porto
Opção: 3

Navios em cais:

Cais 1: Maria_das_ondas (123sq45)
Cais 3: Xpto (123xpto45)
Cais 2: Titanic (ko123)
Cais 4: Gingão (g8932g)
Cais 6: USS_George_Bush (123gb)
Cais 5: HMS_Sheakspeare (123sh)
Cais 8: FaraoDosMares (345ty9)
Cais 9: Solha (sub.pt1)
Cais 10: CacilheiroPerdido (TT456)
Cais 7: NaoVaiAoFundo (sub.pt2)

Navios em espera:

LixoDoMar (petro$$$)
ZeZe_dos_Oceanos (123456)


Controlador do Porto De Lisboa

1. Registar entrada
2. Registar partida
3. Mostrar situação do porto
Opção: 2

Qual a matrícula? sub.pt3

Não está atracado nenhum navio com essa matrícula.


Controlador do Porto De Lisboa

1. Registar entrada
2. Registar partida
3. Mostrar situação do porto
Opção: 2

Qual a matrícula? sub.pt2

Registo de partida efectuado.

Controlador do Porto De Lisboa

1. Registar entrada
2. Registar partida
3. Mostrar situação do porto
Opção: 3

Navios em cais:

Cais 1 : Maria_das_ondas (123sq45)
Cais 3 : Xpto (123xpto45)
Cais 2 : Titanic (ko123)
Cais 4 : Gingão (g8932g)
Cais 6 : USS_George_Bush (123gb)
Cais 5 : HMS_Sheakspeare (123sh)
Cais 8 : FaraoDosMares (345ty9)
Cais 9 : Solha (sub.pt1)
Cais 10 : CacilheiroPerdido (TT456)
Cais 7: LixoDoMar (petro$$$)

Navios em espera:

ZeZe_dos_Oceanos (123456)


Controlador do Porto De Lisboa

1. Registar entrada
2. Registar partida
3. Mostrar situação do porto
Opção: 1

Nome do navio: ReiDosMares
Matrícula: 345ty9

Um navio com essa matrícula já se encontra no porto!

[cotação: 2]
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

Questão 3

Considere a função double produtoInterno(vector <double> const& v1, vector <double> const& v2) que faz o produto interno dos vectores v1 e v2.  Recorda-se que o produto interno de dois vectores é o somatório: v1[0] × v2[0] + v1[1] × v2[1] + ... + v1[n - 1] × v2[n - 1], em que n é a dimensão dos vectores.  A operação produto interno só faz sentido para vectores do mesmo tamanho.

3.1  Indique a  pré-condição (PC), a condição objectivo (CO), a condição invariante (CI) e a guarda (G) do ciclo necessário à construção desta função.

[cotação: 0,5]
 

 

 

 


 
 
 
 
 
 
 
 
 
 
 
 
 

3.2  Defina completamente a função indicada.

[cotação: 1]
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

 

 

3.3  Prove que o ciclo está correcto verificando que:

  1. Se a PC for verdadeira, então a CI também é verdadeira após a inicialização das variáveis e antes da primeira iteração do ciclo, i.e.:
    1. // PC
      init
      // implica CI.
  2. Se a guarda G e a CI  do ciclo forem verdadeiras no início de um passo, então a CI também é verdadeira no fim desse passo, i.e.:
    1. // G e CI
      passo
      // implica CI
  3. Se a guarda G for falsa e a CI for verdadeira, então a CO é verdadeira, i.e.:
    1. // CI e ¬G implicaCO.
[cotação: 1,5]
 
 
 

 

 

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Questão 4

Explique as vantagens para o desenvolvimento de programas de fazer o teste de cada módulo  (classe, função ou procedimento) logo que ele é definido em vez de escrever primeiro a solução completa e compilar e testar apenas no fim.

[cotação: 1]