parte 5 – gestão dinâmica de memória (lista ligada)
Principal vantagem de se usar lista ligada: flexibilidade
O acesso é sequencial, em que cada estrutura contém: os campos e um ponteiro para o próximo elemento da lista
operações com listas ligadas:
1) criar a lista
2) verificar se está vazia
3) pesquisar/lustar
4) adicionar um elemento
5) retirar um elemento
6) destruir a lista
#include <stdio.h> #include <stdlib.h> #include <string.h> #define TAM 100 typedef struct objeto livro, *plivro; struct objeto{ char titulo[TAM], autor[TAM]; int cota; plivro prox; //ponteiro para o proximo elemento da lista }; // int lista_vazia(plivro p); plivro insere_inicio(plivro p); plivro insere_final(plivro p); plivro insere_ordenado(plivro p); void mostra(plivro p); plivro elimina(plivro p); void destruir(plivro p); plivro ler_ficheiro(plivro p); void guarda_ficheiro(plivro p); //2) verificar se está vazia int lista_vazia(plivro p){ if(p==NULL){ return 1; }else{ return 0; } } int menu(){ int i; puts("1 - adiciona livro - inicio"); puts("2 - adiciona livro - final"); puts("3 - adiciona livro - ordenado"); puts("4 - elimina livro"); puts("5 - lista livros"); puts("6 - esvaziar a lista"); puts("7 - carregar lista de um ficheiro"); puts("8 - terminar"); puts("Escolha uma opcao: "); do{ scanf(" %d", &i); }while(i <0 || i >8); return i; } plivro insere_inicio(plivro p){ plivro novo; novo = malloc(sizeof(livro)); //aponta para um qq espaço em memória if(novo == NULL){ printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio"); return p; }else{ printf("Titulo: "); scanf(" %99[^\n]", novo->titulo); printf("Autor: "); scanf(" %99[^\n]", novo->autor); printf("Cota: "); scanf("%d", &novo->cota); //surge agora uma parelha obrigatória novo->prox=p; //aponto o novo para a primeira posição p=novo; //a primeira posição é o novo return p; } free(novo); } plivro insere_final(plivro p){ plivro novo, aux; novo = malloc(sizeof(livro)); //aponta para um espaço em memoria if(novo == NULL){ printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio"); return p; }else{ printf("Titulo: "); scanf(" %99[^\n]", novo->titulo); printf("Autor: "); scanf(" %99[^\n]", novo->autor); printf("Cota: "); scanf("%d", &novo->cota); novo->prox=NULL; //se estiver vazio, insere no inicio if(p == NULL){ p = novo; }else{ //se já tiver pelo menos um elemento aux=p; while(aux->prox != NULL){ aux = aux->prox; } aux->prox = novo; } return p; } free(novo); } plivro insere_ordenado(plivro p){ plivro novo, aux; novo = malloc(sizeof(livro)); //aponta para um espaço em memoria if(novo == NULL){ printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio"); return p; }else{ printf("Titulo: "); scanf(" %99[^\n]", novo->titulo); printf("Autor: "); scanf(" %99[^\n]", novo->autor); printf("Cota: "); scanf("%d", &novo->cota); novo->prox=NULL; //se estiver vazio if(p == NULL || strcmp(novo->titulo, p->titulo) < 0){ //if(p == NULL || novo->cota < p->cota){ novo->prox = p; p = novo; }else{ //se já tiver pelo menos um elemento aux=p; while(aux->prox != NULL && strcmp(novo->titulo, aux->titulo) >0){ //while(aux->prox != NULL && novo->cota > aux->cota){ aux = aux->prox; } novo->prox = aux->prox; aux->prox = novo; } return p; } free(novo); } void mostra(plivro p){ if(p==NULL){ printf("\nerro: lista vazia, sem elementos para listar!\n\n"); }else{ while(p!=NULL){ printf("%s\t%s\t%d\n", p->titulo, p->autor, p->cota); p = p->prox; } } } plivro elimina(plivro p){ int apaga; plivro atual, anterior=NULL; atual= p; if(p==NULL){ printf("\nerro: lista vazia sem informacao\n"); return p; }else{ mostra(p); printf("qual o livro e cota que pretende eliminar?"); scanf("%d", &apaga); while(atual!=NULL && atual->cota != apaga){ anterior = atual; atual = atual->prox; } if(anterior ==NULL){ p = atual->prox; }else{ anterior->prox = atual->prox; } free(atual); return p; } } void destruir(plivro p){ plivro aux; if(p==NULL){ printf("\nerro: nada para apagar!\n"); } while(p!=NULL){ aux = p; p=p->prox; free(aux); } } plivro ler_ficheiro(plivro p){ FILE *f; plivro novo=NULL; if(p!=NULL){ printf("\nerro: lista ja preenchida\n"); return p; }else{ f = fopen("listaLivros.dat", "rb"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return p; }else{ while(feof(f) == 0){ novo = malloc(sizeof(livro)); fread(novo, sizeof(livro), 1, f); novo->prox = p; p = novo; //erro aqui } } } free(novo); fclose(f); return p; } void guarda_ficheiro(plivro p){ FILE *f; f = fopen("listaLivros.dat", "wb"); if(f==NULL){ printf("\n erro no acesso ao ficheiro \n"); return; }else{ while(p != NULL){ fwrite(p, sizeof(livro), 1, f); p=p->prox; } fclose(f); free(p); } } int main() { int escolha; plivro lista = NULL; //1) criar a lista if(lista_vazia(lista)==1){ do{ escolha = menu(); switch(escolha){ case 1: lista = insere_inicio(lista); break; case 2: lista = insere_final(lista); break; case 3: lista = insere_ordenado(lista); break; case 4: lista = elimina(lista); break; case 5: mostra(lista); break; case 6: destruir(lista); break; case 7: lista= ler_ficheiro(lista); break; } }while(escolha != 8); }else{ printf("nao foi possivel inicializar!"); } guarda_ficheiro(lista); return 0; }
Tags : C, Learn C, linguagem C
0 thoughts on “parte 5 – gestão dinâmica de memória (lista ligada)”