Recibo do Exame de 1ª época de Introdução à Programação, 1º semestre de 2001/2002, ISCTE:

Nome do aluno: _______________________________________________

Número do aluno:  ______________________
Assinatura do docente: ________________________________________

Identificação

Nome do aluno: _______________________________________________

Número do aluno:  ______________________

Turma: ____________

Exame de 1ª é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>

using namespace std;

class Dicionário {

  public:
    Dicionário(string const& língua);

    string const& língua() const;
    bool contém(string const& palavra) const;
    int númeroDePalavras() const;

    void insere(string const& palavra);

    void transfereDe(Dicionário origem);

    void mostra() const;


  private:

    vector<string> palavras;
    string const língua_;
};

Dicionário::Dicionário(string const& língua)

    : língua_(língua) {
}

void Dicionário::insere(string const& palavra) {
    palavras.push_back(palavra);
}

void Dicionário::transfereDe(Dicionário origem)
{
    while(not origem.palavras.empty()) {
        palavras.push_back(origem.palavras.back());
        origem.palavras.pop_back();
    }

}

...

int main()
{
    string const português("Português");
    Dicionário dicionário_de_português(português);
    Dicionário const dicionário_de_expressões_usadas_no_vácuo("Expressão no vácuo");
   
...
}

 

1.1  Admita que qualquer uma destas instruções é dada na função main() imediatamente após a definição das variáveis.  Quais das seguintes instruções estão correctas?

__  Dicionário d(dicionário_de_expressões_usadas_no_vácuo.lingua());
__  Dicionário d;
__  Dicionário d(italiano);

[cotação: 1,5]

 

1.2  Admita que qualquer uma destas instruções é dada na função main() do programa acima. Quais das seguintes instruções estão correctas?

__ bool contém_palavra = dicionário_de_português.contém("exame");
__ dicionário_de_português.lingua() = "Castelhano";
__ português = dicionário_de_expressões_usadas_no_vácuo.lingua();
__ int const n =
         dicionário_de_expressões_usadas_no_vácuo.
númeroDePalavras();

[cotação: 2]

 

1.3  Assuma que as seguintes instruções são dadas dentro de uma função ou procedimento membro da classe Dicionário 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?

__  palavras = númeroDePalavras();
__  língua_ = "Castelhano";

 [cotação: 1]

 

 

 

 

 

 


1.4  Assumindo que os restantes métodos da classe estão definidos, qual é o resultado da invocação do seguinte programa?

int main()
{
    Dicionário a("Português europeu");
    a.insere("alquimia");
    a.insere("banana");
    a.insere("dia");

    Dicionário b("Português americano");
    b.transfereDe(a);

    cout << a.númeroDePalavras() << " "
         << b.
númeroDePalavras() << endl;
}

Apenas uma das opções está correcta.

__  3 3
__  0 3
__  3 0
__  0 0

[cotação: 0,5]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Questão 2

Considere o problema de gestão de stocks numa empresa.  No stock da empresa dão entrada lotes, que se carecterizam por ter o nome do produto, a quantidade de unidades do produto nesse lote e o valor unitário do produto nesse lote.  Quando um lote de um produto chega ao armazém da empresa é registado no inventário.  Quando ocorrem saídas de produtos do armazém altera-se o inventário de acordo com a quantidade de produto que saiu do armazém.  A ordem de saída dos produtos respeita a ordem de chegada. Ou seja, começa-se por retirar os produtos do primeiro lote desse produto que tiver dado entrada, continuando-se pelos lotes seguintes (do mesmo produto) até se ter a quantidade pretendida.  O valor de uma saída é calculado somando as multiplicações das quantidade saídas de cada lote pelo valor unitário do produto nesse lote.  O valor dos produtos em stock é calculado somando as multiplicações das quantidades de cada lote inventariado pelo valor unitário do produto nesse lote.

Pretende-se construir um sistema de gestão de stocks de uma empresa que disponha das seguintes funcionalidades:

2.1  Defina a classe C++ Lote que representa um lote de um dado produto. Um lote, como já foi referido, é constituído pelo nome (cadeia de caracteres), quantidade (inteiro) e valor unitário (valor de vírgula flutuante, i.e., double) do produto.  A classe C++ Lote deve dispor de um construtor que recebe os dados necessários à construção de um lote e das seguinte operações:

  1. Uma função de inspecção para o nome do produto;
  2. Uma função de inspecção para a quantidade;
  3. Uma função de inspecção para o valor unitário;
  4. Um modificador que permite diminuir a quantidade de produto de um lote, dada a quantidade que se pretende retirar do lote; e,
  5. Uma operação que exiba no ecrã os dados do lote.

Indique a condição invariante de classe (CIC) e as pré condições de cada operação. Adicione a operação necessária para verificar a CIC.

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.

[cotação: 1]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.2  Defina o construtor da classe Lote e o método que permite verificar a CIC.

[cotação: 0,5]

 

 

 

 

 

 

 

 

 

 

 

 

2.3  Defina as funções de inspecção do nome, da quantidade e valor unitário do produto para a classe Lote, bem como a operação que exibe os dados do lote no ecrã e o modificador que permite diminuir a quantidade de produto do lote.

Coloque instruções de asserção para verificar a condição invariante de classe e as pré-condições nos métodos definidos.

[cotação: 0,5]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.4  Defina a classe C++ Inventário que permite registar os lotes que chegam ao armazém da empresa e as saídas de produto.  Esta classe deve dispor de operações para:

  1. Saber se existe um dado produto no inventário;
  2. Devolver a quantidade de dado produto;
  3. Devolver o valor de uma saída de produto do armazém, dado o nome do produto e a quantidade;
  4. Devolver o valor dos produtos em stock;
  5. Adicionar um novo lote ao inventário;
  6. Remover do inventário uma dada quantidade de um dado produto correspondente a uma saída de produto do armazém;
  7. Mostrar o inventário.

Todos os lotes inventariados têm de ter quantidade superior a zero.  Como não devem existir no inventário lotes com quantidade igual a zero (não fazem sentido), a classe C++ Inventário deve dispor ainda de uma operação privada para realizar a purga dos lotes vazios, isto é, remover todos os lotes cuja quantidade é zero.

Indique qual a condição invariante de classe e as pré-condições das operações.  Adicione a operação necessária para verificar a CIC.

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.

[cotação: 1,5]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.5  Defina o método da classe C++ Inventário que permite saber se dado produto está presente no inventário.

Coloque instruções de asserção para verificar as pré-condições e a condição invariante de classe no método definido.

[cotação: 1]

 

 

 

 

 

 

 

 

 

2.6  Defina o método da classe C++ Inventário que devolve o valor dos produtos em stock.  

Coloque instruções de asserção para verificar as pré-condições e a condição invariante de classe no método definido.

[cotação: 1]

 

 

 

 

 

 

 

 

 

 

2.7  Defina os métodos da classe C++ Inventário para:

Coloque instruções de asserção para verificar as pré-condições e a condição invariante de classe nos métodos definidos.

[cotação: 1,5]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.8  Escreva um programa que utilize as classes anteriores para simular a componente de gestão de stocks de uma empresa.  O programa deve mostrar o menu:

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

no ecrã, permitindo assim ao utilizador escolher entre as operações possíveis.  Quando a opção 0 for escolhida o programa terminará.

Se a opção 1 for escolhida, o programa deve perguntar qual o nome do produto, a quantidade e o valor unitário, e adicionar ao inventário o lote constituído por essa informação.

Se a opção 2 for escolhida, o programa deve perguntar qual o nome do produto e a quantidade que irá sair do armazém. Se o produto não existir em stock o programa deve avisar o utlizador. Se o produto não existir em quantidade suficiente o programa deve avisar o utilizador. Se não ocorrer nenhuma destas situações, o programa deve mostrar o valor da saída e realizá-la.

Se for escolhida a opção 3, deve ser exibido no ecrã o valor dos produtos em stock.  Caso seja escolhida a opção 4, exibe-se o inventário.

Exemplo de execução:

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 1

Nome do produto: batata
Quantidade: 100
Valor unitário: 0.7

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 4

batata    100    0.7

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 1

Nome do produto: cebola
Quantidade: 50
Valor unitário: 0.85

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 1

Nome do produto: batata
Quantidade: 100
Valor unitário: 0.5

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 4

batata    100    0.7
cebola     50    0.85
batata    100    0.5

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 2

Nome do produto: banana
Quantidade: 20

O produto banana não existe em stock.

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 2

Nome do produto: batata
Quantidade: 150

O valor da saída é 95.

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 4

cebola    50    0.85
batata    50    0.5

1 - Entrada de lote
2 - Saída de produto
3 - Valor dos produtos em stock

4 - Mostra inventário

0 - Terminar

Opção: 3

O valor dos produtos em stock é 67.5.

[cotação: 1]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Questão 3

Com a entrada do Euro em circulação, a necessidade de realizar conversões de valores entre unidades monetárias generalizou-se.  O nosso objectivo é simplificar o trabalho ao grande número de pessoas que ainda necessitam de realizar conversões para melhor compreender o real valor dos bens e serviços.

Defina uma classe Conversor que permita converter valores, dada a taxa de conversão.

Deve definir a classe e os seguintes métodos:

  1. Conversor::Conversor(double const taxa_de_conversão, int const precisão = 2) que constrói um conversor com taxa de conversão taxa_de_conversão e precisão precisão.
  2. vector<double> Conversor::conversãoDe(vector<double> const& valores) const que devolve a conversão do vector valores.
  3. void Conversor::mostraTabela(double const valor_inicial, double const valor_final, double const incremento) const que exibe no ecrã uma tabela de conversão de valor_inicial a valor_final com incrementos de incremento.
  4. Uma função de inspecção para a taxa de conversão.
  5. Uma função de inspecção para a precisão.
  6. void Conversor::estabelecePrecisão(int const precisão) que permite alterar o valor da precisão.

e a função

  1. double arredondamentoDe(double const valor, int const precisão), sabendo que double Conversor::conversãoDe(double const valor) const definido como

    double Conversor::conversãoDe(double const valor) const
    {
        return arredondamentoDe(valor * taxa_de_conversão, precisão_);
    }

    devolve a conversão do valor valor.

de modo a que o seguinte código seja válido:

Conversor conversor(200.482);
cout << conversor.conversaoDe(1) << endl; //
Aparece 200.48
                                          // Note que .48 aparece porque a precisão é 2
conversor.estabelecePrecisão(0);
cout << conversor.conversaoDe(2) << endl; //
Aparece 401
                                          // Note que não aparece parte decimal porque a precisão é 0

Caso seja necessário pode usar a função double pow(double base, int expoente) para calcular potências.

[cotação: 3,5]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Questão 4

Considere a função int índiceDoMáximoDe(vector<int> const& v) que devolve o índice do valor máximo que ocorre num vector:

int índiceDoPrimeiroMáximoDe(vector<int> const& v)
{
    int índice_do_máximo = 0;

    for(vector<int>::size_type i = 1; i != v.size(); ++i)
        if(v[índice_do_máximo] < v[i])
            índice_do_máximo = i;

    return índice_do_máximo;
}

4.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: 1]

 

 

 

 

 

 

 

 

 

4.2  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.:
      // 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.:
      // 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.:
      // CI e ¬G implica CO.
[cotação: 1,5]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Questão 5

Explique resumida mas claramente os conceitos de abstracção e encapsulamento.

[cotação: 1]