Recibo do Exame de 2ª Época de Introdução à Programação (IGE/ETI), 1º semestre de 2001/2002, ISCTE:
Nome do aluno: _______________________________________________
Número do aluno: ______________________
Assinatura do docente: ________________________________________
Exame de 2ª Época
Introdução à Programação
IGE e ETI
1º semestre de 2001/2002
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 (Atenção: o código não tem erros de compilação, mas pode ter erros
lógicos):
#include <iostream>
#include <string>
#include <vector>
class Mapa {
public:
typedef std::string Chave;
typedef int Valor;
Mapa(Valor const& valor_inicial = Valor());
Valor const& valorDe(Chave const& chave) const;
Valor& valorDe(Chave const& chave);
void mudaValorDePara(Chave const& chave, Valor const& valor);
private:
struct Par {
Par(Chave const& chave = Chave(),
Valor const& valor = Valor());
std::string chave;
int valor;
};
std::vector<Par>::size_type
indiceDeParCom(Chave const& chave) const;
Valor const valor_inicial;
mutable std::vector<Par> pares_acedidos;
};
Identificação
Nome do aluno: _______________________________________________
Número do aluno: ______________________
Turma: ____________
Mapa::Par::Par(Chave const& chave_, Valor const& valor_)
...
: chave(chave_), valor(valor_)
{
}
using namespace std;
int main()
{
...
Mapa m1;
Mapa m2(35);
Mapa const m3(47);
}
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 (i.e., não produzem erros de compilação)?
__ cout << m1.valorDe(12) << endl;
__ m2.valorDe('a') = 10;
__ m3.valorDe("a") = 10;
[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 (i.e.,
não produzem erros de compilação)?
__ cout << m1.valor_inicial << endl;
__ m2 = m1;
__ m3.mudaValorDePara("a", 10);
[cotação: 1,5]
1.3 Quais das seguintes definições do construtor da classe estão correctas (i.e., não produzem erros de compilação)?
__ Mapa::Mapa(Valor const& valor_inicial_) { valor_inicial =
valor_inicial_; }
__ Mapa::Mapa(Valor const& valor_inicial) : valor_inicial(valor_inicial)
{ }
[cotação: 1]
1.4 Suponha as seguintes definições dos métodos acima declarados:
std::vector<Mapa::Par>::size_type
Mapa::indiceDeParCom(Chave const& chave) const
{
std::vector<Par>::size_type i = 0;
while(i != pares_acedidos.size() and pares_acedidos[i].chave != chave)
++i;
return i;
}
Mapa::Valor const& Mapa::valorDe(Chave const& chave) const
{
std::vector<Par>::size_type i = indiceDeParCom(chave);
if(i == pares_acedidos.size())
pares_acedidos.push_back(Par(chave, valor_inicial));
return pares_acedidos[i].valor;
}
Mapa::
Valor&
Mapa::
valorDe(Chave const& chave)
{
std::vector<Par>::size_type i = indiceDeParCom(chave);
if(i == pares_acedidos.size())
pares_acedidos.push_back(Par(chave, valor_inicial));
return pares_acedidos[i].valor;
}
void
Mapa::
mudaValorDePara(Chave const& chave, Valor const& valor)
{
std::vector<Par>::size_type i = indiceDeParCom(chave);
if(i == pares_acedidos.size())
pares_acedidos.push_back(Par(chave, valor));
else
pares_acedidos[i].valor = valor_inicial;
}
Suponha ainda que está bem definido o construtor da classe.
Suponha o seguinte programa:
int main()
{
Mapa m1;
Mapa m2(35);
Mapa const m3(47);
m2.mudaValorDePara("a", 10);
cout << m2.valorDe("a") << ' ' << m2.valorDe("b") << endl;
}
Qual é o resultado da invocação do programa? Apenas uma das opções está correcta. O código apresentado pode conter erros lógicos!
__
O código está errado! Não chega a
compilar, muito menos executar...
__ 10 35
O programa está errado! Ao executar aborta, não
chegando a mostrar nada.
__ 35 35
__
[cotação: 1]
Identificação
Nome do aluno: _______________________________________________
Número do aluno: ______________________
Turma: ____________
Questão 2
Considere o problema da gestão de viagens num autocarro de transporte de passageiros internacional. A lotação de cada autocarro é arbitrária, mas sempre positiva. Qualquer pessoa pode reservar um bilhete, bastando para isso indicar o seu nome. Contudo, o bilhete que o afecta a um lugar só é emitido quando o cliente efectua a respectiva compra. Até lá a reserva permanece numa colecção de reservas associadas à viagem. Num determinado prazo antes do início da viagem, todas as reservas de bilhetes existentes perdem validade, tendo o mesmo tipo de tratamento das desistências. A partir desse momento não são possíveis mais reservas, admitindo-se apenas vendas directas de bilhetes. Uma desistência de uma reserva implica a sua eliminação da colecção de reservas. Não é possível desistir da viagem depois de comprado o bilhete. Não é necessário que o cliente faça uma reserva para que possa comprar um bilhete: basta dirigir-se a um ponto de venda e efectuar a compra, sendo-lhe atribuído um lugar de imediato, se tal for possível. A venda dos bilhetes envolve a identificação da pessoa que o adquire através do seu nome. A atribuição de lugares no autocarro é feita sequencialmente, i.e., o primeiro lugar livre encontrado é atribuído ao cliente, a menos que este demonstre preferência por algum lugar. Neste último caso, o cliente deverá indicar o número do lugar pretendido (após ter efectuado a consulta dos lugares vagos).
Como a empresa optou por uma política de overbooking, poderá aceitar reservas para uma viagem até atingir uma taxa de sobrelotação de 10%, i.e., a empresa poderá aceitar reservas se o número de reservas actuais somado com o número de lugares já ocupados não superar 110% da capacidade do autocarro. A venda de bilhetes só pode ser realizada desde que haja lugares livres no autocarro e não se tenha excedido a sobrelotação de 10%.
Pretende-se nesta questão construir e testar uma parte do sistema de gestão de viagens.
Leia o enunciado completo desta questão antes de começar a responder a cada uma das suas alíneas!
2.1 Defina uma classe Bilhete
representando
bilhetes vendidos. As instâncias desta classe devem possuir as seguintes propriedades:
A classe Bilhete
deve possuir as seguintes operações (operando
sobre as suas instâncias):
Indique qual a condição invariante da classe e as pré-condições das operações. Adicione a operação necessária para verificar a CIC.
Indique claramente quais das operações 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: 0,5]
Em cada uma das alíneas seguintes considere como completas a resolução das alíneas que lhe são anteriores, mesmo que as não tenha realizado.
2.2 Considere a seguinte classe:
/**
Representa a informação relativa a uma viagem de um autocarro, i.e., que lugares estão
vagos e que lugares já foram vendidos e a quem.
@invariant
Constrói nova viagem associada a um dado autocarro. Todos os lugares estão
*/
class Viagem {
public:
/**
inicialmente vagos.
@pre
matrícula_do_autocarro
<> "" e 0 <número_de_lugares
.*/
Viagem(string const& matrícula_do_autocarro,
int const número_de_lugares);
/**
Devolve o número de lugares do autocarro.
@pre V.
*/
int númeroDeLugares() const;
/**
Devolve o número de lugares vagos no autocarro nesta viagem.
@pre V.
*/
int númeroDeLugaresVagos() const;
/**
Devolve o número de lugares no autocarro já vendidos para esta viagem.
@pre V.
*/
int númeroDeLugaresVendidos() const;
/**
Devolve o número de lugares no autocarro já vendidos (através de
uma reserva)
para esta viagem.
@pre V.
*/
int númeroDeLugaresVendidosComReserva()const;
/**
Devolve o número de lugares no autocarro já vendidos (sem reserva prévia)
para esta viagem.
@pre V.
*/
int númeroDeLugaresVendidosSemReserva()const;
/**
Devolve o número do primeiro lugar vago no autocarro para esta viagem.
@pre
númeroDeLugaresVagos
() <> 0.*/
int primeiroLugarVago() const;
/**
Indica se o lugar com o número dado está vago no autocarro para esta viagem.
@pre 0 <=
numero_do_lugar
e<
numero_do_lugarnumero_de_lugares
.*/
bool estáVagoOLugarComNúmero(int const número_do_lugar) const;
/**
Indica se existe algum bilhete vendido a um dado cliente.
@pre V.
*/
bool háBilheteVendidoAClienteComNome(string const& nome) const;
/**
Mostra no ecrã informação associada ao lugar cujo número é dado.
@pre 0 <=
numero_do_lugar
e
numero_do_lugar
<numero_de_lugares
.*/
void mostraLugarComNúmero(int const número_do_lugar) const;
/**
Mostra no ecrã toda a informação associada à viagem.
@pre V.
*/
void mostra() const;
/**
Vende um bilhete com base numa reserva prévia.
@pre 0 <=
numero_do_lugar
enumero_do_lugar
<numero_de_lugares
e<> "" e
nome_do_cliente
¬
haBilheteVendidoAClienteComNome
(nome_do_cliente
) e
0 <=
número_da_reserva
e(
estáVagoOLugarComNúmeronúmero_do_lugar
).*/
void vendeBilhete(int const número_do_lugar,
string const& nome_do_cliente,
int const número_da_reserva);
/**
Vende um bilhete sem reserva prévia.
@pre 0 <=
numero_do_lugar
enumero_do_lugar
<numero_de_lugares
e<> "" e
nome_do_cliente
¬
haBilheteVendidoAClienteComNome
(nome_do_cliente
) e
estáVagoOLugarComNúmero
(número_do_lugar
).*/
void vendeBilhete(int const número_do_lugar,
string const& nome_do_cliente);
private:
/**
Indica se a condição invariante de classe é verdadeira.@pre V.
*/
bool cumpreInvariante() const;
};
Complete parcialmente a classe declarando os seus atributos, indicando a sua condição invariante (use os espaços na definição da classe) e definindo os seguintes métodos:
void vendeBilhete(int const número_do_lugar,
string const& nome_do_cliente,
int const número_da_reserva);
int númeroDeLugaresVendidosComReserva()const;
bool háBilheteVendidoAClienteComNome(string const&
nome) const;
Coloque instruções de asserção verificando as pré-condições dos métodos definidos bem como a condição invariante de classe.
[cotação: 2]
2.3 Considere as seguintes classes:
/**
Representa uma reserva de bilhete.@invariant
nome_do_cliente
<> "" e 0 <=número_
.*/
class Reserva {
public:
Constrói uma nova reserva para um dado cliente e com um dado número.
/**
@pre
nome_do_cliente
<> "" e 0 <=número
.*/
Reserva(string const& nome_do_cliente, int const número);
/**
Devolve o nome do cliente que fez a reserva.@pre V.
*/
s
tring const& nomeDoCliente() const;
/**
Devolve o número da reserva.@pre V.
*/
int número() const;
/**
Mostra no ecrã informação sobre a reserva.@pre V.
*/
void mostra() const;
private:
string nome_do_cliente;
int número_;
/**
Indica se a condição invariante de classe é verdadeira.@pre V.
*/
bool cumpreInvariante() const;
};
/**
Representa uma colecção de reservas de uma qualquer viagem.@invariant
*/
class ColecçãoDeReserva {
public:
Constrói uma nova colecção vazia de reservas.
/**@pre V.
*/
ColecçãoDeReserva();
/**
Indica se a colecção contém alguma reserva de um dado cliente.@pre V.
*/
bool contémReservaDeClienteComNome(string const& nome_do_cliente)
const;
/**
Indica se a colecção contém alguma reserva com um dado número.@pre V.
*/
bool contémReservaComNúmero(int const número_da_reserva) const;
/**
Devolve o número da reserva feita por um dado cliente.@pre
contémReservaDeClienteComNome
(nome_do_cliente
).*/
int númeroDaReservaDoClienteComNome(string const& nome_do_cliente)
const;
/**
Devolve o nome do cliente que fez a reserva com um dado número.@pre
contémReservaComNúmero
(número_da_reserva
).*/
string const& nomeDoClienteComReservaNumero(
int const número_da_reserva) const;
/**
Mostra no ecrã toda a informação associada à colecção de reservas.
@pre V.
*/
void mostra() const;
/**
Devolve o número de reservas na colecção.@pre V.
*/
int tamanho() const;
/**
Reserva um bilhete para um dado cliente. O número da reserva é atribuído
automaticamente.
@pre ¬
contémReservaDeClienteComNome
(nome_do_cliente
).*/
void reservaBilheteParaClienteComNome(
string const& nome_do_cliente);
/**
Cancela a reserva com o número dado.@pre
contémReservaComNúmero
(número_da_reserva
).*/
void cancelaReservaComNúmero(int const número_da_reserva);
/**
Cancela todas as reservas da colecção.@pre V.
*/
void esvazia();
private:
/**
Indica se a condição invariante de classe é verdadeira.@pre V.
*/
bool cumpreInvariante() const;
};
Complete
parcialmente a classe ColecçãoDeReserva
declarando os seus atributos,
indicando a sua condição invariante (use o espaço
na definição da classe) e definindo os seguintes métodos:
int númeroDaReservaDoClienteComNome(string const& nome_do_cliente)
const;
void reservaBilheteParaClienteComNome(string
const& nome_do_cliente);
void cancelaReservaComNúmero(int const número_da_reserva);
Coloque instruções de asserção verificando as pré-condições dos métodos definidos bem como a condição invariante de classe.
[cotação: 2]
2.4 Defina a classe GestorDeViagem
que gere uma viagem num
dado autocarro. Deve incluir as seguintes operações:
Indique qual a condição invariante da classe e as pré-condições das operações. Adicione a operação necessária para verificar a CIC.
Indique claramente quais das operações da classe não alteram a instância implícita.
Faça uso das
classes Viagem
e ColecçãoDeReserva
das alíneas
anteriores.
Não é necessário nesta questão definir qualquer um dos métodos. Coloque comentários indicando claramente para que serve cada uma dos atributos que declarar.
[cotação: 1,5]
2.5 Defina os
seguintes métodos da classe GestorDeViagem
:
[cotação: 2]
2.6 Escreva um
programa que simule a Gestão de uma Viagem numa autocarro de matrícula 45-45-XX
com 10 lugares. O programa deve simular a
criação de uma nova viagem. 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:
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 1
Qual o nome do cliente? João Braz
Número da reserva: 0
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 1
Qual o nome do cliente? Ana Pedro
Número da reserva: 1
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 2
Qual o número da reserva? 1
Quer indicar um lugar [s/n]? n
O número do lugar será 0
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 3
Qual o nome do cliente? João Braz
Cliente já existe!
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 3
Qual o nome do cliente? Pedro
Quer indicar o número do lugar [s/n]? s
Lugar 0 está ocupado
Lugar 1 está vago
Lugar 2 está vago
Lugar 3 está vago
Lugar 4 está vago
Lugar 5 está vago
Lugar 6 está vago
Lugar 7 está vago
Lugar 8 está vago
Lugar 9 está vago
Qual o número do lugar? 6
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 5
Autocarro: 45-45-XX
Número de lugares: 10
Número do lugar: 0
Nome do cliente: Ana Pedro
Número da reserva de origem: 1
Número do lugar: 6
Nome do cliente: Pedro
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 6
Reserva nº 0
Nome do cliente: João Braz
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 4
Qual o número do lugar? 6
Lugar número 6:
Está ocupado por Pedro...mais tarde...
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 1
Máxima sobrelotação atingida!
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 7
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 1
Reservas encerradas!
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 3
Qual o nome do cliente? 3
Quer indicar o número do lugar [s/n]? s
Lugar 0 está ocupado
Lugar 1 está vago
Lugar 2 está vago
Lugar 3 está vago
Lugar 4 está vago
Lugar 5 está vago
Lugar 6 está ocupado
Lugar 7 está vago
Lugar 8 está vago
Lugar 9 está vago
Qual o número do lugar? 5
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 3
Qual o nome do cliente? José
Quer indicar o número do lugar [s/n]? n
O número do lugar será 1
1 Reservar bilhete
2 Vender bilhete com reserva
3 Vender bilhete sem reserva
4 Ver informação sobre um lugar
5 Ver estado da viagem
6 Ver colecção de reservas
7 Encerrar reservas
0 Sair
Opção: 0
Boa Viagem
[cotação: 2]
Identificação
Nome do aluno: _______________________________________________
Número do aluno: ______________________
Turma: ____________
Questão 3
Considere a
função int númeroDeAprovações(vector<int> const& notas)
e que indica, com base
no vector de notas fornecido, o número de alunos que ficaram aprovados, i.e., nota
superior ou igual a 10.
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
init
//
implica CI.
//
G e CI
passo
//
implica CI
//
CI e ¬G implica CO.
[cotação: 1,5]
Questão 4
Muitas linguagens de programação (e.g., C++) são muito permissivas quanto à organização "gráfica" do código. Por exemplo, em C++ os três pedaços de código que se seguem são equivalentes:
return (
i
);
return(i);
return i;
No entanto, é comum usarem-se determinadas formas convencionais (e por isso com algum grau de arbitrariedade) de grafar o código. Discuta os méritos ou deméritos da existência destas convenções gráficas e do seu seguimento no desenvolvimento de código.
Diga também qual o objectivo das regras mais ou menos precisas de nomenclatura de identificadores (i.e., regras de atribuição de nomes a classes e rotinas, por exemplo) que são usadas nesta disciplina.
[cotação: 2]