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:
1.1 Admita que qualquer uma destas instruções é dada na função
#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;
...
}
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:
Assumindo que os restantes métodos da classe estão definidos, qual é o resultado da invocação do programa?
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;
}
__ 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:
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):
ConjuntoDeRegistosDeNavios()
constrói um novo
conjunto (vazio) de registos de navios.RegistoDeNavio registoDeNavioComMatrícula(string const&
matrícula) const
devolve uma cópia do registo do navio do conjunto
com a matrícula indicada, que se admite pertencer a algum dos registos no
conjunto (pré-condição).bool contémRegistoDeNavioComMatrícula(string
const& matrícula) const
devolve verdadeiro se o conjunto contiver
o registo de um navio com a matrícula dada.
void mostra() const
mostra no ecrã todos os registos de navios que se
encontram no conjunto.void insere(RegistoDeNavio const& registo_de_navio)
acrescenta um registo de navio a um conjunto, admitindo que não existe no
conjunto nenhum outro registo com a mesma matrícula do registo passado como
argumento (pré-condição).void removeRegistoDeNavioComMatrícula(string const&
matrícula)
remove do conjunto o registo do navio com a matrícula
indicada, que se admite pertencer a algum dos registos no conjunto (pré-condição).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:
void ConjuntoDeRegistosDeNavio::insere(RegistoDeNavio
const& registo_de_navio)
void ConjuntoDeRegistosDeNavio::removeRegistoDeNavioComMatrícula(string
const& matrícula)
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:
FilaDeRegistosNavios()
constrói uma nova fila
(vazia) de registos de navios.RegistoDeNavio primeiro() const
devolve uma
cópia do registo do navio que está na frente da fila, admitindo-se que a
fila não está vazia (pré-condição).bool contémRegistoDeNavioComMatrícula(string
const& matrícula) const
devolve verdadeiro se a fila contiver o
registo de um navio com a matrícula dada.
bool vazia() const
devolve verdadeiro se a fila estiver vazia.
bool cheia() const
devolve verdadeiro se a fila estiver cheia.
void mostra() const
mostra no ecrã todos os registos de navios que se
encontram na fila.int comprimento() const
devolve o número de
registos de navios que se encontram na fila.void põe(RegistoDeNavio const& registo_de_navio)
acrescenta um registo de navio a uma fila, admitindo-se que não existe na
fila nenhum outro registo com a mesma matrícula do registo passado como
argumento e que a fila não está cheia (pré-condição).void tira()
remove o primeiro registo de navio
da fila, que se admite não estar vazia (pré-condição).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:
RegistoDeNavio primeiro() const
devolve uma
cópia do registo do navio que está na frente da fila, admitindo-se que a
fila não está vazia (pré-condição).
bool vazia() const
devolve verdadeiro se a fila estiver vazia.void põe(RegistoDeNavio const& registo_de_navio)
acrescenta um registo de navio a uma fila, admitindo que não existe na fila
nenhum outro registo com a mesma matrícula do registo passado como
argumento e que a fila não está cheia (pré-condição).void tira()
remove o primeiro registo de navio
na fila, que se admite não estar vazia (pré-condição).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:
ControladorDoPorto
dado o
número de cais do porto em questão (e.g. 10).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
:
ControladorDoPorto
dado o
número de cais do porto em questão (e.g. 10).[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:
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:
//
PC
//
implica CI.//
G e CI
//
implica CI//
CI e ¬G implicaCO.
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]