Aula prática 4

Sumário

Objectivos

Os alunos no final desta aula deverão conhecer:

  1. O conceito de ponteiro na linguagem C++ e operações associadas.
  2. A relação entre ponteiros e matrizes usada no C++.
  3. A organização em memória de uma matriz em C++.
  4. A vantagem notacional da utilização de ponteiros para implementar cadeias ligadas sobre uma matriz de dimensão fixa.

Deverão também ser capazes de:

  1. Implementar completamente, usando ponteiros, as classes listas e iterador à custa de matrizes de dimensão fixa em que os itens são elos de duas cadeias disjuntas: uma cadeia duplamente ligada com guardas contendo os elos da matriz ocupados com itens e uma cadeia simplesmente ligada sem guardas contendo os elos da matriz livres.
  2. Implementar pequenos algoritmos de manipulação de cadeias ligadas usando ponteiros.
  3. Escrever pequenos programas usando ponteiros para manipular informação no formato de matrizes.

Caso os alunos sintam que os objectivos não foram atingidos na totalidade deverão concluir/repetir os exercícios desta aula autonomamente e ou recorrer aos horários de dúvidas.

Resumo

O resumo da matéria abordada nesta aula prática pode ser consultado aqui.

Material de apoio

Os ficheiros relativos a esta aula estão disponíveis no arquivo Aula4.zip.

Exercícios

1.  Considere as classes ListaDeTelefonema e ListaDeTelefonema::Iterador desenvolvidos na Aula prática 3 (pode encontrar os ficheiros lista_de_telefonema.H, lista_de_telefonema_impl.H e lista_de_telefonema.C no directório ~/POO/Aula4).  

1.a)  Altere a implementação das classes ListaDeTelefonema e ListaDeTelefonema::Iterador de modo a recorrer unicamente a  ponteiros e não a índices.  Cada elo das cadeias deve guardar, para além do item, ponteiros para os elos anterior e seguinte da cadeia.  A associação entre iteradores e listas deve passar a ser feita usando ponteiros, e não referências como até aqui.

Altere as classes, atributos e operações e respectivos métodos pela seguinte ordem:

Quando terminar chame o docente, que lhe dirá onde encontrar os ficheiros lista_de_telefonema.H, lista_de_telefonema_impl.H e lista_de_telefonema.C que definem as classes ListaDeTelefonema e ListaDeTelefonema::Iterador já totalmente convertidas de modo a usarem ponteiros.

Figura 4.1

1.b)  Compare a remoção de itens feita usando a nova implementação com ponteiros (refira-se à Figura 4.1) com a remoção definida na Aula prática 3.  Quais as diferenças?  São relevantes?  Conceptuais ou meramente sintácticas?

1.c)  A operação da classe ListaDeTelefonema::Iterador que devolve o item referenciado pelo iterador deve passar a chamar-se operator*, por analogia com os ponteiros:

ListaDeTelefonema::Item& ListaDeTelefonema::Iterador::operator*() const;

Altere o seu nome.

1.d)  Enriqueça a classe ListaDeTelefonema com operações que cumpram as seguintes funcionalidades e que respeitem os cabeçalhos dados:

  1. Transferência do conteúdo de uma lista para uma outra (de lista para a instância implícita):

    void ListaDeTelefonema::transfereDe(ListaDeTelefonema& outra_lista);

  2. Devolução de iterador referenciando a última ocorrência de um determinado item na lista:

    ListaDeTelefonema::Iterador ListaDeTelefonema::ultimaOcorrenciaDe(Item const& item);

    Para implementar o método acima é conveniente que a classe Telefonema tenha o operador == definido.
  3. Acréscimo de itens à instância implícita (concatenação de duas listas):

    ListaDeTelefonema& ListaDeTelefonema::operator+=(ListaDeTelefonema const& outra_lista);


2.  Escreva o seguinte programa e execute-o.  Interprete e comente o resultado.

int main()
{
    int i = 2;
    int* p1 = &i;
    int* p2 = &i;
    *p1 = 3;
    cout << *p1 << " " << *p2 << " " << i << endl;
}


3.  Compile o programa mostra_matriz.C, que se encontra em ~/POO/Aula4, e execute-o.  Interprete o resultado e comente profusamente o programa.


4.  Reescreva o procedimento mostra() sem usar quaisquer variáveis locais (lembre-se que uma matriz, quando parâmetro de uma rotina, é na realidade um ponteiro).