| Linha | Codigo |
| 001 | // Prof. Leo^nidas - http://www.matematica.br http://line.ime.usp.br |
| 002 | // MAC0122 - 2017/09 |
| 003 | |
| 004 | // Introducao `as listas ligadas em C |
| 005 | // Principio: usando alocacao dinamica de memoria, podemos usar registros e apontadores para definir a ordem dos dados. |
| 006 | // Exemplo de lista com insercao ao final |
| 007 | // Se 'prox' tiver com o valor nulo (NULL), entao a lista finalizou. |
| 008 | |
| 009 | // Para ajudar na depuracao, compilar com diretivas para verificar acesso `a posicoes invalidas (via apontadores ou vetores) |
| 010 | // $ gcc -fsanitize=address -g -o introducao_lista_ligada introducao_lista_ligada.c |
| 011 | |
| 012 | #include <stdio.h> |
| 013 | #include <string.h> // para 'strcpy(...)' |
| 014 | #include <stdlib.h> // para o 'malloc(...)' e 'free(...)' |
| 015 | |
| 016 | #define TAM 10 // limite para numero de caracteres em campo do registro |
| 017 | #define M 5 // limite para vetor de registros |
| 018 | |
| 019 | typedef struct reg { // define estrutura 'dado' |
| 020 | int id; |
| 021 | char nome[TAM]; // precisa deste espaco |
| 022 | struct reg *prox; // aponta para uma estrutura 'dado' |
| 023 | } tipoRegistro; |
| 024 | |
| 025 | // Cria um registro devolvendo um apontador para ele |
| 026 | tipoRegistro *criaRegistro (char *nome, int id) { |
| 027 | tipoRegistro *item = malloc(sizeof(tipoRegistro)); |
| 028 | //tipoRegistro *item = malloc(TAM * sizeof(char) + sizeof(int) + sizeof(tipoRegistro *)); |
| 029 | strcpy(item->nome, nome); |
| 030 | item->id = id; |
| 031 | item->prox = NULL; |
| 032 | return item; |
| 033 | } |
| 034 | |
| 035 | // Construir uma lista ligada de itens (registros), inserindo sempre na ultima posicao |
| 036 | // Exercicios 1. Implementar uma funcao que insere na ultima posicao (ja' no codigo, mas dentro da "main") |
| 037 | // Exercicios 2. Implementar uma funcao que remova o elemento cujo campo 'nome' tenha determinado valor |
| 038 | // Exercicios 3. Implementar uma funcao que remova o elemento cujo campo 'id' tenha determinado valor |
| 039 | // ATENCAO: nos exercicios 2 e 3, cuidado com situacoes extremas (lista vazia, item a ser removido ser o primeiro ou ser o ultimo) |
| 040 | int main (void) { |
| 041 | int i; |
| 042 | char nomes[][TAM] = { "aluno 1", "aluno 2", "aluno 3", "aluno 4", "aluno 5" }; // vetor de nomes estatico (para NAO precisar digitar...) |
| 043 | tipoRegistro *primeiro, *apont, *novo; |
| 044 | |
| 045 | primeiro = criaRegistro(nomes[0], 0); // crie o primeiro elemento |
| 046 | apont = primeiro; |
| 047 | for (i=1; i<5; i++) { |
| 048 | novo = criaRegistro(nomes[i], i); // crie novo elemento |
| 049 | apont->prox = novo; // faca com que o apontador para proximo do ultimo aponte para este novo registro |
| 050 | apont = novo; |
| 051 | } |
| 052 | apont = primeiro; |
| 053 | while (apont!=NULL) { |
| 054 | printf(" - %d : %s\n", apont->id, apont->nome); |
| 055 | // Depois de usar, se NAO mais precisar do registro pode devolve-lo ao "banco de memoria" usando |
| 056 | // free(apont); |
| 057 | apont = apont->prox; // pegue o proximo registro |
| 058 | } |
| 059 | |
| 060 | return 0; |
| 061 | } |