Curso completo de linguagem C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
track25.html
25. Lista - <list>
25.1 Visão geral
A estrutura lista é implementada pela classe genérica list e funciona de maneira
semelhante a uma corrente com a movimentação de entrada e saída de elos nas
duas extremidades, aonde também os elos podem ser acrescentados ou retirados
de qualquer posição dessa corrente.
A melhor maneira de visualizar o potencial da estrutura lista, é imaginar
uma linha do itinerário de um ônibus aonde as paradas podem ser excluídas
ou adicionadas nas extremidades da rota geral do ônibus, e qualquer parada
em qualquer ponto do trajeto pode ser deletada e/ou inserida para reparo
do itinerário.
Em programação de jogos você pode destinar a lista para duas finalidades, por
exemplo em um jogo de nave com orientação norte-sul ou oeste-leste, você pode
mapear uma linha de tiros aonde você destrói as balas da extremidade final que
sairam do campo de visão, e você adiciona balas na extremidade inicial da
linha por causa do evento de atirar acionado pelo jogador.
Em outro exemplo, a lista também pode ser usada para mapear um caminho, com
novas posições sendo adicionadas ou retiradas das extremidades, inserindo
ou excluindo de qualquer posição pontos desfavoráveis do caminho sendo
mapeado.
Em um programa de desenhos vetoriais a lista pode ser usada para guardar as
formas geométricas desenhadas pelo usuário. Em uma operação de desfazer você
pode remover facilmente o último ato executado da lista. Na edição do desenho
você consegue acrescentar facilmente qualquer outra figura em qualquer outra
posição utilizando a estrutura lista.
// lista_tst.cpp
// Esse programa exemplica o uso de listas
#include <iostream>
#include <string>
#include <list>
using namespace std;
list<string> smetroLista;
list<string>::iterator ncx_pos = 0;
string metro[10];
void mostrar_lista() {
for( ncx_pos = smetroLista.begin(); ncx_pos != smetroLista.end(); ++ncx_pos )
cout << *ncx_pos << "--";
cout << endl << endl;
} // fim da função: mostrar_lista()
int main() {
system("color f0"); system("title lista_tst.cpp"); cout << endl;
// Nossso metro virtual....
metro[1] = "(1)SP";
metro[2] = "(2)Diadema";
metro[3] = "(3)SBC";
metro[4] = "(4)SA";
metro[5] = "(5)SC";
metro[6] = "(6)Maua";
metro[7] = "(7)Santos";
metro[8] = "(8)RJ";
metro[9] = "(9)MG";
// Vamos inserir dados na frente da lista
smetroLista.push_front( metro[4] );
smetroLista.push_front( metro[3] );
smetroLista.push_front( metro[2] );
smetroLista.push_front( metro[1] );
// Vamos inserir dados no fundo da lista
smetroLista.push_back(metro[5] );
smetroLista.push_back(metro[7] );
smetroLista.push_back(metro[8] );
smetroLista.push_back(metro[9] );
cout << "\tEsquecemos de colocar a cidade #6" << endl;
mostrar_lista();
// Opa! Esquecemos de adicionar o metro[6] na lista antes do [7].
// Vamos primeiro obter o iterator que aponta para a posicao aonde queremos
// inserir nosso dado. Vamos fazer uma busca linear para encontrar esta
// posicao.
cout << "\tColocamos Maua' de volta no mapa..." << endl;
for( ncx_pos = smetroLista.begin(); ncx_pos != smetroLista.end(); ++ncx_pos )
if( *ncx_pos == metro[7] ) break;
// Vamos inserir o metro[6] aonde esta' o [7]. Isso nao deleta o [7], isso...
// ...insere o [6] entre o [5] e o [7].
smetroLista.insert(ncx_pos, metro [6] );
mostrar_lista();
// Vamos deletar alguns itens...
cout << "\tDeletamos o metro[7], a frente e o fundo da lista...\n";
smetroLista.remove( metro[7]);
smetroLista.pop_front();
smetroLista.pop_back();
mostrar_lista();
cout << endl;
system("pause");
} // endfunction: main()
Declarando a lista
#include <list>
list<string> smetroLista;
list<string>::iterator ncx_pos = 0;
O bloco de código acima exemplifica os passos necessários para utilização de
uma lista no programa. Você deve incluir o arquivo da classe list (#include <list>),
declarar uma lista na forma da sintaxe list<tipo_de_dado> nome_da_lista; e,
como provavelmente você vai querer navegar pelos dados, você deve declarar
um iterator na forma list<tipo_de_dado>::iterator nome_do_iterator; para
acessá-los.
Colocando dados na lista
Você pode adicionar dados facilmente no início e no fim da lista utilizando
respectivamente os métodos .push_front (elemento) e .push_back (elemento) do
objeto da classe list.
Porém para determinar a posição aonde o dado vai ser inserido você deve usar
um iterator obtido com os métodos .begin() ou .end() realizando o
deslocamento relativo a estas posições na forma de um pequeno looping, ex.:
ncx_pos = smetroLista.begin();
for (int mypos=1; mypos < 3; mypos++) ncx_pos++;
smetroLista.insert ( ncx_pos, "03 - ta' hackeado!");
Em nosso programa exemplo issso foi feito dessa forma:
// Opa! Esquecemos de adicionar o metro[6] na lista antes do [7].
// Vamos primeiro obter o iterator que aponta para a posicao aonde queremos
// inserir nosso dado. Vamos fazer uma busca linear para encontrar esta
// posicao.
cout << "\tColocamos Maua' de volta no mapa..." << endl;
for( ncx_pos = smetroLista.begin(); ncx_pos != smetroLista.end(); ++ncx_pos )
if( *ncx_pos == metro[7] ) break;
// Vamos inserir o metro[6] aonde esta' o [7]. Isso nao deleta o [7], isso...
// ...insere o [6] entre o [5] e o [7].
smetroLista.insert(ncx_pos, metro [6] );
Veja que utilizamos um looping for para avançar o iterator.
Removendo elementos
Remover elementos é simples com esses métodos:
.pop_front() - remove o item da frente da lista;
.pop_back() - remove o item do fim da lista;
.remove( elemento ) - remove diretamente o elementos especificado.
Reveja como fizemos em nosso programa:
// Vamos deletar alguns itens...
cout << "\tDeletamos o metro[7], a frente e o fundo da lista...\n";
smetroLista.remove( metro[7]);
smetroLista.pop_front();
smetroLista.pop_back();
Obtendo o tamanho da lista
O tamanho da lista é obtido com o método .size().