Recibo do Exame de Introdução à Programação (ETI), 1º semestre de 1999/2000, 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

ETI

1º semestre de 1999/2000

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:
    A(const char c = ' ', const int m = 1, const int n = 0);
    string f1(const char);
    int f2(int);
    char f3();
    unsigned t;
  private:
    string s;
    string f1(const unsigned);
};

...

int main()
{
    const char c = '0';
    A am('a', 3);
    vector<char> u(2);
    vector<int> v(2);
    u[0] = 'X';
    u[1] = 'M';
    v[0] = 7;
    v[1] = 13;
    ...
}


 

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

__  A a(u[0], v[0], v[1]);
__  A a(c);
__  A a(u[0], u, v[0]);

 [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?

__ c = am.f3();
__ string s = am.f1(3U);
__ int k = am.f2(c - '0');
__ am.t = v[0] + v[1];

 [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?

__  am.t = f2(s.size());
__  s = f1(t);
 [cotação: 1]

1.4  Suponha o seguinte:

A::A(const char c, const int m, const int n)
    : t(n) {
    for(int i = 0; i != m; ++i)
        s += c;
}
char A::f3() {
    if(t == s.size())
        return s[0];
    return char('a' + t);
}
int main() {
    A a('x'), b('b', 3, 2);
    cout << a.f3() << "   " << b.f3() << 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.

__   x   b
__   a   c
__   a   b
__   x   a

 [cotação: 0,5]
Questão 2

Considere um projecto de trabalho numa empresa.  Um projecto de trabalho é constituído por várias tarefas que têm um dado ínicio e uma dada duração (ambos em dias).  Admita que o projecto se inicia no dia 1 e os restantes dias são contandos a partir daqui.  Em determinadas situações, como é o caso de certas reestruturações, é necessário adicionar ou remover tarefas de um projecto.  Naturalmente, só é possível remover tarefas que ainda não tenham começado, assim como só é possível adicionar tarefas com início depois do dia em que o projecto se encontra.

2.1  Defina a classe Tarefa de modo a guardar:

  1. A identificação da tarefa (uma cadeia de caracteres).
  2. O início da tarefa.
  3. A duração da tarefa.
A classe Tarefa deve dispor de um construtor com três parâmetros, sendo estes a sua identificação, o seu início e a sua duração.  Além disso deve dispôr de funções membro que permitam inspeccionar a identificação, o ínicio e a duração de cada tarefa.  Este construtor deve poder ser invocado sem passar qualquer argumento (nesse caso a identificação é a cadeia vazia "", o início é 0, e a duração é 0).

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 Tarefa.

[cotação: 0,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.3  Defina as funções de inspecção da identificação, início e duração para a classe Tarefa.

[cotação: 0,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.4  Defina a classe Projecto que deve guardar a informação sobre as tarefas que o projecto compreende, bem como o dia actual do projecto.  Deve declarar os métodos necessários para:

  1. Adicionar uma nova tarefa ao projecto.  Não é permitida a inserção de tarefas cujo início seja inferior ou igual ao dia actual do projecto.
  2. Remover uma tarefa do projecto, dada a sua identificação.  Não é permitida a remoção de tarefas em curso ou já terminadas.
  3. Avançar o dia actual.
  4. Devolver um booleano que indica se o projecto está concluído ou não.  O projecto está concluído se não existirem quaisquer tarefas em curso ou por realizar.
  5. Mostrar todas as tarefas do projecto, indicando se estão terminadas, em curso ou por iniciar.
Deve ainda declarar um construtor que irá iniciar o dia actual do projecto com 0, significando isto que o projecto ainda não começou.

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.  Coloque comentários indicando claramente para que serve cada uma das variáveis membro que definir.

[cotação: 2]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.5  Defina o método da classe Projecto que remove uma tarefa do projecto dada a sua identificação.

[cotação: 2]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.6  Defina o método da classe Projecto que adiciona uma nova tarefa ao projecto.

[cotação: 1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.7  Escreva um programa que utilize a classe Projecto (descrita e definida anteriormente).  Este programa deve inicialmente construir um projecto com n tarefas, n dado pelo utilizador do programa.  Para cada tarefa deve ser perguntado ao utilizador qual a sua identificação, o seu início e a sua duração.  Em seguida, o programa deverá simular o funcionamento do projecto até este terminar, isto é, até que todas as tarefas estejam terminadas.  A simulação terá início com o avanço do dia actual do projecto para o dia 1 e prosseguirá avançando dia a dia.  Em cada dia do projecto deverá ser exibido ao utilizador do programa o seguinte menu:

  1. Adicionar tarefa - permite adicionar uma nova tarefa, devem ser pedidos os dados da tarefa.
  2. Remover tarefa - permite remover uma tarefa, deve ser pedida a identificação da tarefa.
  3. Sair - sai do menú.
Este menú permitirá à empresa gerir as tarefas do seu projecto.  No fim de cada dia deverá ser exibido o estado do projecto, ou seja, todas as suas tarefas indicando o estado de cada uma e finalmente deve ser avançado o dia actual do projecto.

[cotação: 1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Questão 3

Defina completamente uma classe (ListaDePalavras) que permite manipular um texto de modo a obter listagem das palavras que o constituem.  Deve declarar a classe e definir:

  1. O construtor ListaDePalavras::ListaDePalavras(const string& nome_do_ficheiro) que recebe como argumento o nome de um ficheiro e constrói a lista de palavras que constituem (sem repetições).  Este construtor não deve poder ser utilizado para converter implicitamente de string para ListaDePalavras.
  2. Um método void ListaDePalavras::mostra() const que permite visualizar no ecrã a lista construída.
Deve ainda sobrecarregar o operador += que permite somar uma instância da classe ListaDePalavras a outra.  Isto significa acrescentar à instância usada como operando esquerdo do operador todas as palavras da instância usada como segundo operando (e, novamente, evitando as repetições).

Supondo que o ficheiro texto.txt tem o seguinte conteúdo:

isto é um teste
claro que poderia não ser um teste
mas é um
O seguinte troço de programa
ListaDePalavras l1("texto.txt");

l1.mostra();

escreve no ecrã:
isto
é
um
teste
claro
que
poderia
não
ser
mas
Se o conteúdo de texto2.txt for:
isto é o segundo teste
poderia haver outros
mas não há
O seguinte troço de programa
ListaDePalavras l1("texto.txt");
ListaDePalavras l2("texto2.txt");
l1 += l2;

l1.mostra();

teria como resultado:
 
isto
é
um
teste
claro
que
poderia
não
ser
mas
o
segundo
poderia
haver
outros
[cotação: 3,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Questão 4

Considere a função int decimal(const int m[], const int n) que devolve o inteiro correspondente ao número na base 8 recebido como uma matriz de dígitos de tamanho n.  Para compreender melhor como se interpreta um número na base 8, atente no seguinte exemplo:

(271)8  = 185

(271) 8 = 2×82 + 7×81 + 1×80 = 2×64 + 7×8  + 1×1 = 128 + 56 + 1 = 185

A função deve poder ser usada como se segue:
int m[3] = {2, 7, 1};
int valor = decimal(m, 3);
cout << "O valor é: " << valor << '.' << endl;
que escreve no ecrã
O valor é 185.
Admita que está disponível a seguinte função:
// PC: n >= 0
// CO: potência = xn
int potência(const int x, const int n)
{
    int potência = 1;
    for(int i = 0; i != n; ++i)
        potência *= x;
    return potência;
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

4.1  Dada a pré-condição n > 0, indique 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]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

4.2  Defina completamente a função indicada.

[cotação: 1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

Questão 5

Explique brevemente o que é a Condição Invariante de Instância (CII) de uma classe (lembre-se da classe Racional).  Para que serve?

[cotação: 1]