Recibo do Exame de 2ª época de Introdução à Programação, 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 de 2ª época

Introdução à Programação

IGE e 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(string const& p, int const n = 1);

    string f1() const;
    int soma() const;

    void p1(string const& c);
    void p2(int const n);

    string s;

  private:
    vector<int> x;

    bool f2(int const n) const;
};

A::A(string const& p, int const n)

    : s(p) {
    x.push_back(n);
}

...

int main()
{
    const A a("um", 1);
    A b("dois", 2);
    ...
}


 

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

__  A c;
__  A c(a);
__  A c("quatro");

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

__ char c = a.s[1];
__ a.p1("uns");
__ bool l = b.f2(22);
__ b.s = f1();

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

__  x = 0;
__  f2(10) = false;

 [cotação: 1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

1.4  Suponha o seguinte:

void A::p2(int const n) {
    x.push_back(n);
}

int A::soma() const {
    int total = 0;
    for(vector<int>::size_type i = 0; i != x.size(); ++i)
        total += x[i];
    return total;
}

void f(A const& a, unsigned int& n)
{
    if(a.s.length() > n) {
        n += a.s.length();
        return;
    }
    n = a.soma();
}

Assumindo que os restantes métodos da classe estão definidos, qual é o resultado da invocação do seguinte programa?
int main()
{
    A a("uns", 11);

    a.p2(1);
    unsigned int b = 2;
    f(a, b);
    cout << b;

    a.p2(101);
    f(a, b);
    cout << " " << b << endl;
}

Apenas uma das opções está correcta.

__   2   2
__   5   2
__   5   113
__   2   113

 [cotação: 0,5]
 

Questão 2

Considere a organização de uma conferência internacional.  Pretende-se para esta conferência construir um painel com as bandeiras de todos os países intervenientes.  Cada bandeira é identificada pelo nome do país e pelas suas dimensões reais (largura × altura).

2.1  Defina a classe Bandeira de modo a guardar:

  1. O nome do país (cadeia de caracteres).
  2. A altura (número decimal).
  3. A largura (número decimal).
A classe Bandeira deve dispor de um construtor com três parâmetros, sendo estes o nome do país, a altura e a largura da bandeira.  Além disso deve dispor de funções membro que permitam inspeccionar o nome do país, a altura e a largura da bandeira.  Deve ainda dispor de uma função que devolve a área da bandeira.  O construtor deve poder ser invocado sem se passar qualquer argumento, sendo neste caso o nome do país a cadeia vazia (""), a altura 0 e a largura 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 Bandeira.

[cotação: 0,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.3  Defina as funções de inspecção do nome do país, da largura e da altura da bandeira para a classe Bandeira, bem como a função que devolve a área da bandeira.

[cotação: 0,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.4  Defina a classe Painel que deve guardar a colecção de bandeiras que o compõem.  Dado que a sala reservada para o acontecimento dispõe de um número de lugares limitado, definiu-se como número máximo de países participantes 30.  Deve declarar os métodos necessários para:

  1. Inserir uma bandeira no painel.
  2. Retirar uma bandeira no painel, dado o nome do país.
  3. Verificar se o painel está vazio.
  4. Verificar se o painel está completo (cheio).
  5. Verificar se a bandeira de um dado país existe no painel.
  6. Devolver a bandeira, dado o nome do país.
  7. Devolver a área (mínima) do painel (calculada somando as áreas de todas as bandeiras).
  8. Mostrar painel (usando apenas os nomes dos países).
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: 1,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.5  Defina o método da classe Painel que insere uma bandeira no painel.  Deve inserir mesmo que já exista no painel uma bandeira para o mesmo país.

[cotação: 0,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.6  Defina o método da classe Painel que retira uma bandeira do painel.  Se não existir no painel uma bandeira do país indicado, não faz nada.  Se existirem duas ou mais bandeiras para esse país, deve retirar a última que foi colocada na colecção.

[cotação: 1,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.7  Defina o método da classe Painel que mostra os países do painel no ecrã.  Todas as linha mostradas devem ter exactamente o mesmo número de países, excepto num caso descrito mais à frente.  Devem ser mostrados tantos países por linha quantos possível, mas nunca menos de 2 nem mais de 5.  Se a única solução for mostrar apenas um país por linha, devem-se mostrar exactamente 5 países por linha com excepção da última linha.

Exemplos:

Se o número de países participantes for:
[cotação: 1,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.8  Escreva um programa que utiliza a classe Painel para simular o painel deste evento internacional.  Este programa deve inicialmente construir um painel com n bandeiras, n dado pelo utilizador do programa.  Para cada bandeira deve ser perguntado ao utilizador qual o nome do país, a altura e a largura da bandeira.  Tenha em atenção que se for introduzido um nome de um país já introduzido no painel, o programa deve pedir um outro nome de país, uma nova altura e largura da bandeira.  Ou seja, no final devem existir as n bandeiras inicialmente previstas pelo utilizador.  Em seguida, o programa deve mostrar o painel no ecrã.  Por fim, deve mostrar a área do painel.

[cotação: 0,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Questão 3

Defina uma classe (MatrizBidimensional) que permita manipular matrizes bidimensionais de double (pode assumir que o número máximo de linhas e colunas é 20).  Deve declarar a classe e definir os seguintes métodos:

  1. void MatrizBidimensional::lê() que permite ler os valores da matriz do teclado (organizados por linha).
  2. void MatrizBidimensional::mostra() const que permite visualizar no ecrã uma variável do tipo MatrizBidimensional no seguinte formato (não se preocupe com alinhamentos!):

  3.     2.3 1.4 3.9
        3.1 0.5 2.2
        6.7 7.3 4.1
        9.7 1.1 2.3
  4. double& MatrizBidimensional::em(int const linha, int const coluna) que devolve uma referência para o elemento da matriz na posição indicada (aborta o programa se a posição for inválida).
  5. double MatrizBidimensional::em(int const linha, int const coluna) const que devolve o valor do elemento da matriz na posição indicada (aborta o programa se a posição for inválida).
Declare também duas funções de inspecção: uma para o número de linhas e outra para o número de colunas.  Não é necessário definir estas funções.

Defina um construtor adequado, que estabeleça o número de linhas e colunas da matriz (por omissão uma matriz tem dimensão 1 × 1).

Deve também definir o operador * que permite multiplicar duas matrizes.  Se o número de colunas da primeira matriz for diferente do número de linhas da segunda matriz o programa deve abortar.

Esta classe deve suportar as seguintes instruções:

MatrizBidimensional a(3,2);   // define uma matriz bidimensional com 3 linhas e quatro colunas

a.le();    // admita-se que foram introduzidos os números 2.0 3.2 1.0 1.1 3.0 4.1

a.mostra();

// Aparece no ecrã:
//     2 3.2
//     1 1.1
//     3 4.1

MatrizBidimensional b(2,1);

b.le();    // foram introduzidos os números 2.0 1.0
b.mostra();

// Aparece no ecrã:
//     2
//     1

MatrizBidimensional c = a * b;

c.mostra();
 
 

// Aparece no ecrã:
//     7.2
//     3.1
//     10.1

[cotação: 3,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Questão 4

Considere a função int posicaoDe(int const m[], int const n, int const k) que devolve a posição do elemento da matriz m de dimensão n que tem o valor kO valor k existe sempre na matriz m.

4.1  Dada a pré-condição n > 0 e (E j : 0 <= j < n : m[j] = k), 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 implica CO.
[cotação: 1]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

4.4  Usando a função anterior, defina uma função int posicaoDeOuN(int const m[], int const n, int const k) que devolve a posição do elemento da matriz m de dimensão n + 1 que tem o valor k. Neste problema, k pode não existir na matriz m. Se k não ocorrer em m, a função devolve n.  Note que neste caso a pré-condição é n >= 0 e que a matriz tem n + 1 elementos.  Ou seja, a matriz tem n elementos mais um elemento extra que pode ser preechido em qualquer altura, com qualquer valor. Use essa posição para que a resolução deste problema possa ser realizada usando a função definida na alínea 4.2.

[cotação: 0,5]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Questão 5

Diferencie membros de classe de membros de instância.  Como declarar membros de classe?  Qual a sua utilidade?

[cotação: 1]