Ir ao conteúdo

Posts recomendados

Postado

[DUVIDA] - Lista dinamica(encadeada). Estou com duvidas nessa lista, parei na parte de inserção no fim. Quando eu insiro no fim e imprimo, só aparece caracteres estranhos. No inserir inicio imprime normalmente:

essa função recebe o meu ponteiro inicio!



void inserir_final(TIPO_ELEMENTO *lista)
{
    SetConsoleTitle("INSERIR FINAL");
    TIPO_ELEMENTO *inicio=lista->proximo;
    if(saida==0)
    {
        printf("\n\nCrie o encadeamento primeiro");
    }
    else
    {
        char nome[10];
        TIPO_ELEMENTO *novo_elemento=malloc(sizeof(TIPO_ELEMENTO));
        printf("\n\nDigite o pais: ");
        scanf("%s",novo_elemento->pais);
        novo_elemento->proximo=NULL;
        while(inicio!= NULL)
        {
            if(inicio->proximo == NULL)
            {
                inicio->proximo=novo_elemento;

                return;
            }
            inicio=inicio->proximo;
        }
    }
}

 

 

Postado

Essa função faz muitas ações que teoricamente é um problema de arquitetura.

 

As boas práticas recomendadas dizem que a responsabilidade de um membro deve ser única. Tome por exemplo o método SetConsoleTitle, que modifica o título da janela e só.

void inserir_final( TIPO_ELEMENTO * lista )
{   SetConsoleTitle( "INSERIR FINAL" );
    
    TIPO_ELEMENTO * inicio= lista->proximo; /* O que acontece se 
    `proximo` é NULL? */
    
    if( saida == 0 ) /* O que é isso... saída ???????? */
    {   printf("\n\nCrie o encadeamento primeiro");     }
    else
    {   char            nome[10]; /* Pra quê serve esse objeto ?????????????? */
        TIPO_ELEMENTO * novo_elemento= malloc( sizeof (TIPO_ELEMENTO) );

        printf( "\n\nDigite o pais: " );
        scanf( " %s", novo_elemento->pais ); /* esse método falhará pra nomes
        compostos? */
        
        novo_elemento->proximo= NULL;
        
        while( inicio != NULL )
        {   if( inicio->proximo == NULL )
            {   inicio->proximo= novo_elemento;
                return;
            }
            inicio= inicio->proximo;
}   }   }

* "Se um método ultrapassar 20 linhas é porque precisa ser dividido. Isso é poesia."

Postado
10 horas atrás, AnsiC disse:

"Se um método ultrapassar 20 linhas é porque precisa ser dividido. Isso é poesia."

Gostei dessa frase! 

Postado
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <stdbool.h>
int saida=0;
bool primeiro=false;

typedef struct Elemento
{
    char pais[10];
    struct Elemento *proximo;

} TIPO_ELEMENTO;
TIPO_ELEMENTO *inicio;
TIPO_ELEMENTO *navegador;
TIPO_ELEMENTO *fim;

void criar_cadeia()
{
    if(saida==0)
    {
        inicio=malloc(sizeof(TIPO_ELEMENTO));
        inicio->proximo=NULL;

        navegador=malloc(sizeof(TIPO_ELEMENTO));
        navegador->proximo=NULL;
        printf("Cadeia criada com sucesso\n\n");
        saida=1;
    }
    else
    {
        printf("Cadeia ja foi criada\n\n");
    }
    printf("Pressione ENTER para continuar");
    system("pause>NULL");
}
void inserir_inicio(TIPO_ELEMENTO *inicio)
{
    SetConsoleTitle("INSERIR INICIO");
    if(saida==0)
    {
        printf("\n\nCrie o encadeamento primeiro");
    }
    else
    {
        char nome[10];
        TIPO_ELEMENTO *novo_elemento=malloc(sizeof(TIPO_ELEMENTO));
        printf("\n\nDigite o pais: ");
        scanf("%s",novo_elemento->pais);

        inicio->proximo=novo_elemento;
        novo_elemento->proximo=navegador;
        navegador=novo_elemento;
    }
    printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");
}
void inserir_final(TIPO_ELEMENTO *lista)
{
    SetConsoleTitle("INSERIR FINAL");
    TIPO_ELEMENTO *inicio=lista->proximo;
    if(saida==0)
    {
        printf("\n\nCrie o encadeamento primeiro");
    }
    else
    {


        char nome[10];
        TIPO_ELEMENTO *novo_elemento=malloc(sizeof(TIPO_ELEMENTO));
        printf("\n\nDigite o pais: ");
        scanf("%s",novo_elemento->pais);
        novo_elemento->proximo=NULL;
   if(lista==NULL){
            novo_elemento->proximo=NULL;
            lista=novo_elemento;
        }else{

              while(inicio!= NULL)
        {
            if(inicio->proximo == NULL)
            {
                inicio->proximo=novo_elemento;

                return;
            }
            inicio=inicio->proximo;
        }






        }

    }




}

int quantidade(TIPO_ELEMENTO *lista)
{
    int qtd=0;
    if(saida==0)
    {
        return 0;
    }
    else
    {
        TIPO_ELEMENTO *list=lista->proximo;

        while(list!=NULL)
        {
            if(list->proximo==NULL)
            {
                return qtd;
            }
            qtd++;
            list=list->proximo;
        }
    }

}
void listar_lista(TIPO_ELEMENTO *lista)//conferido certo começa no primeiro elemento, e quando null da break
{
    int i=1;
    TIPO_ELEMENTO *list=lista->proximo;
    while(list!=NULL)
    {

        printf("\n\n\tCadastro %d\n\n",i);
        printf("Nome do pais: %s\n",list->pais);
        i++;
        list=list->proximo;
        if(list->proximo==NULL)
        {
            break;
        }

    }
    printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");
}
int menu()
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
    WORD saved_attributes;

    GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
    saved_attributes = consoleInfo.wAttributes;
    SetConsoleTitle("MENU");
    int op;
    system("cls");
    printf("\n\n\t\t\t\t\t");
    SetConsoleTextAttribute(hConsole, BACKGROUND_GREEN);
    printf("Cadastros feitos ate o momento: %d\n\n\n",quantidade(inicio));
    SetConsoleTextAttribute(hConsole, saved_attributes);

    printf("1 - criar encadeamento\n\n");
    printf("2 - Inserir no inicio\n\n");
    printf("3 - Inserir no meio\n\n");
    printf("4 - Inserir no fim\n\n");
    printf("5 - Retirar do inicio\n\n");
    printf("6 - Retirar do meio\n\n");
    printf("7 - Retirar do fim\n\n");
    printf("8 - Buscar\n\n");
    printf("9 - Listar \n\n");
    printf("10 - Sair \n\n");
    printf("Digite a opcao desejada: ");
    scanf("%d",&op);
    system("cls");
    return op;

}
int main()
{
    system("mode con:cols=115 lines=35");
    int op;


    do
    {
        system("cls");
        op=menu();
        switch(op)
        {
        case 1:
            criar_cadeia();
            break;
        case 2:
            inserir_inicio(inicio);
            break;
        case 3:
            break;
        case 4:
            inserir_final(inicio);
            break;
        case 5:
            break;
        case 6:
            break;
        case 7:
            break;
        case 8:
            break;
        case 9:
            listar_lista(inicio);

            break;
        case 10:
            exit(0);
            break;
        }
    }
    while(1);
    system("pause");
    return 0;
}

Desculpe Ansic, o que eu poderia melhorar nessa parte de estrutura do codigo? E porque não estou conseguindo printar quando eu adiciono no final?No inserir inicio da tudo certo..

 

Postado

Pessoal, conferem ai, acho que eu to errando na atribuição do inicio. EU mando uma variavel copia percorrer a lista mas não mando o inicio realmente de volta.

Postado

Olá @s4lezardv1A Apenas gostaria de comentar a respeito de um ponto: É possível sim trabalhar com uma lista encadeada definindo o tipo de retorno das funções que fazem alterações na lista, seja de inserção, remoção, etc.. ser do tipo void.

Porém, pessoalmente, me parece mais viável, após ser feita cada alteração em uma lista, retornar a mesma atualizada, ou seja, se é feita uma inserção de um elemento na lista, retornar a lista com esse novo elemento. Dessa forma, a gente vai ter sempre a nossa disposição a lista, tal como falei, atualizada. É apenas uma sugestão

Outro ponto é q me parece mais lógico, com relação a alocação de memória, apenas alocar memória quando um novo elemento é inserido na lista, dessa forma, a quantidade de memória alocada vai aumentando ou diminuindo de acordo com a operação que é feita e, com isso, fica mais fácil para liberar essa memória depois. Para pequenos códigos não liberar a memória alocada pode não trazer maiores problemas, mas para projetos maiores isso resultaria em problemas sérios e reais

Seria isso. São apenas dois comentários que vi ser necessário fazer. Mas claro, fica a seu critério levar em consideração o que foi dito ou não

E, claro, já aproveitando, gostaria de recomendar um tutorial sobre lista encadeada que o instrutor de um curso de C q fiz me passou, quando procurei esse instrutor para dizer q estava encontrando muita dificuldade para trabalhar com listas encadeadas

Segue o tutorial:

 

Cap 10 - Lista Encadeada.pdf

 

Esse tutorial tem me ajudado muito e creio q vai ser muito útil para você também!

 

Postado

@giu_d. Sempre é valido toda a informação passada,muito obrigado. Estou a pouco tempo cursando analises, então é bom não pegar vicios que fazem o codigo não fluir de forma pratica. Quanto a primeira informação. Deixa eu entender: Eu estou recebendo minha lista como parametro de referencia, e estou alterando ela com uma variavel interna isso né? você diz que é mais pratico, receber essa lista ainda como parametro, só que retornar essa mesma lista, isso? Se sim, eu mandando ela como parametro, ela não atualizaria sempre tambem?

Quanto a alocaçao eu arrumei o codigo, Agora somente quando eu insiro um novo elemento eu reservo um espaço na memoria. Eu aloquei tambem um espaço para o INICIO por pensar que para existir a lista eu necessitaria criar ela, com o inicio recebendo um espaço, parecido com o que eu fiz na lista estatica. Estou na duvida agora....
CODIGO CORRIGIDO: 
Se puderem conferir se ficou certo. Gosto muito de receber criticas construtivas, vai me ajudar no futuro, então se puderem ver o que posso melhorar:
OBS: ainda não finalizei o Inserir meio.

 

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <stdbool.h>
int saida=0;
bool primeiro=false;

typedef struct Elemento
{
    char pais[10];
    struct Elemento *proximo;

} TIPO_ELEMENTO;
TIPO_ELEMENTO *inicio;
void criar_cadeia()
{
    if(saida==0)
    {
        inicio=malloc(sizeof(TIPO_ELEMENTO));
        inicio->proximo=NULL;
        printf("Cadeia criada com sucesso\n\n");
        saida=1;
    }
    else
    {
        printf("Cadeia ja foi criada\n\n");
    }
     printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");
}
void inserir_inicio(TIPO_ELEMENTO *inicio)
{
    SetConsoleTitle("INSERIR INICIO");
    if(saida==0)
    {
        printf("\n\nCrie o encadeamento primeiro");
    }
    else
    {
           char nome[10];
            TIPO_ELEMENTO *novo_elemento=malloc(sizeof(TIPO_ELEMENTO));
            printf("\n\nDigite o pais: ");
            scanf("%s",novo_elemento->pais);
        if(inicio->proximo==NULL)
        {

            novo_elemento->proximo=NULL;
        }
        else
        {
            novo_elemento->proximo=inicio->proximo;
        }
                    inicio->proximo=novo_elemento;
    }
    printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");
}
void inserir_meio(TIPO_ELEMENTO *inicio){
if(saida==0)
    {
        printf("\n\nCrie o encadeamento primeiro");
    }
    else
    {
        int pos=0;
printf("Digite uma posicao:");
scanf(" %d",&pos);



    }
 printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");
}




void inserir_final(TIPO_ELEMENTO *inicio)
{

    if(saida==0)
    {
        printf("\n\nCrie o encadeamento primeiro");
    }
    else
    {
        char nome[10];
        TIPO_ELEMENTO *novo_elemento=malloc(sizeof(TIPO_ELEMENTO));
        novo_elemento->proximo=NULL;
        TIPO_ELEMENTO *auxiliar=inicio;
        printf("\n\nDigite o pais: ");
        scanf("%s",novo_elemento->pais);
        if(inicio->proximo==NULL)//se a lista não tiver cadastro ainda
        {
            inicio->proximo=novo_elemento;
        }
        else
        {
            while(auxiliar->proximo!=NULL)
            {
                auxiliar=auxiliar->proximo;
                if(auxiliar->proximo==NULL)
                {
                    auxiliar->proximo=novo_elemento;

                    return;
                }
            }
        }
    }
    printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");
}



int quantidade(TIPO_ELEMENTO *lista)
{
    int qtd=0;
    if(saida==0)
    {
        return 0;
    }
    else
    {
        TIPO_ELEMENTO *list=lista;

        while(list->proximo!=NULL)
        {
            qtd++;
            list=list->proximo;
        }
        return qtd;
    }

}
void listar_lista(TIPO_ELEMENTO *lista)//conferido certo começa no primeiro elemento, e quando null da break
{
    if(saida==0){
        printf("\n\nCrie o encadeamento primeiro");
    }else{
    int i=1;
    TIPO_ELEMENTO *list=lista->proximo;
    while(list!=NULL)
    {

        printf("\n\n\tCadastro %d\n\n",i);
        printf("Nome do pais: %s\n",list->pais);
        i++;
        list=list->proximo;
    }
    }
    printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");

}
void menu()
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
    WORD saved_attributes;

    GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
    saved_attributes = consoleInfo.wAttributes;
    SetConsoleTitle("MENU");
    int op;
    do{
    system("cls");
    printf("\n\n\t\t\t\t\t");
    SetConsoleTextAttribute(hConsole, BACKGROUND_GREEN);
    printf("Cadastros feitos ate o momento: %d\n\n\n",quantidade(inicio));
    SetConsoleTextAttribute(hConsole, saved_attributes);

    printf("1 - criar encadeamento\n\n");
    printf("2 - Inserir no inicio\n\n");
    printf("3 - Inserir no meio\n\n");
    printf("4 - Inserir no fim\n\n");
    printf("5 - Retirar do inicio\n\n");
    printf("6 - Retirar do meio\n\n");
    printf("7 - Retirar do fim\n\n");
    printf("8 - Buscar\n\n");
    printf("9 - Listar \n\n");
    printf("10 - Destruir \n\n");
    printf("11 - Sair \n\n");
    printf("Digite a opcao desejada: ");
    scanf("%d",&op);
    system("cls");
        switch(op)
        {
        case 1:
            criar_cadeia();
            break;
        case 2:
            inserir_inicio(inicio);
            break;
        case 3:
            inserir_meio(inicio);
            break;
        case 4:
            inserir_final(inicio);
            break;
        case 5:
            break;
        case 6:
            break;
        case 7:
            break;
        case 8:
            break;
        case 9:
            listar_lista(inicio);
            break;
        case 10:
            if(saida==0){
        printf("\n\nNao existe lista para destruir.");
            }else{
                       free(inicio);
                       saida=0;
                               printf("\n\nLista destruida.");

            }
               printf("\n\n\n\n\t\t\t\tPressione ENTER para continuar");
    system("pause>NULL");
            break;
             case 11:
            exit(0);
            break;
        }
    }
    while(1);
}
int main()
{
    system("mode con:cols=115 lines=35");
    menu();

    system("pause");
    return 0;
}

 

Postado

Olá @s4lezardv1A Desculpa a demora em responder. É q tive q me ausentar um pouco

Para mostrar de maneira mais simples o que estou querendo passar com relação ao comentário q fiz acima, apenas montei um pequeno código q ilustra de maneira prática essa lógica. As funções do código abaixo eu peguei do tutorial q te passei acima

Creio q com esse código vai entender a lógica q comentei acima, com respeito a retornar a lista atualizada com as alterações feitas

Segue o código:

#include <stdio.h>
#include <stdlib.h>

struct lista {
    int info;
    struct lista* prox;
};

typedef struct lista Lista;

/* Declaração dos protótipos das funções */
Lista *inicializa(void);
void imprime(Lista *);
Lista *retira(Lista *, int);
void libera(Lista *);
Lista *ordena(Lista *);

/* função de inicialização: retorna uma lista vazia */
Lista* inicializa (void)
{
    return NULL;
}

/* inserção no início: retorna a lista atualizada */
Lista* insere (Lista* l, int i)
{
    Lista* novo = malloc(sizeof(Lista));
    novo->info = i;
    novo->prox = l;
    return novo;
}


/* função imprime: imprime valores dos elementos */
void imprime (Lista* l)
{
    Lista* p; /* variável auxiliar para percorrer a lista */
    for (p = l; p != NULL; p = p->prox)
        printf("info = %d\n", p->info);

    printf("\n");
}

Lista *ordena(Lista *l) {

    Lista *p = l; /* ponteiro para percorrer a lista*/
    Lista *t;
    int temp;

    while (p != NULL) {
        t = p->prox;
        while (t != NULL) {
            if (t->info < p->info) {
                temp = p->info;
                p->info = t->info;
                t->info = temp;
            }
            t = t->prox;
        }
        p = p->prox;
    }

    return l;
}


/* função retira: retira elemento da lista */
Lista* retira (Lista* l, int v) {
    Lista* ant = NULL; /* ponteiro para elemento anterior */
    Lista* p = l; /* ponteiro para percorrer a lista*/
    /* procura elemento na lista, guardando anterior */
    while (p != NULL && p->info != v) {
        ant = p;
        p = p->prox;
    }
    /* verifica se achou elemento */
    if (p == NULL)
        return l; /* não achou: retorna lista original */
    /* retira elemento */
    if (ant == NULL) {
        /* retira elemento do inicio */
        l = p->prox;
    }
    else {
        /* retira elemento do meio da lista */
        ant->prox = p->prox;
    }
    free(p);

    return l;
}


void libera (Lista* l)
{
    Lista* p = l;
    while (p != NULL) {
        Lista* t = p->prox; /* guarda referência para o próximo elemento */
        free(p); /* libera a memória apontada por p */
        p = t; /* faz p apontar para o próximo */
    }
}

int main (void) {

    Lista* l; /* declara uma lista não iniciada */
    l = inicializa(); /* inicia lista vazia */
    l = insere(l, 23); /* insere na lista o elemento 23 */
    l = insere(l, 45); /* insere na lista o elemento 45 */
    l = insere(l, 56); /* insere na lista o elemento 56 */
    imprime(l);

    l = ordena(l); /* ordena a lista em ordem crescente */
    imprime(l);

    l = insere(l, 78); /* insere na lista o elemento 78 */
    imprime(l);
    l = retira(l, 78);
    imprime(l);
    l = retira(l, 45);
    imprime(l);
    
    libera(l);
    
    return 0;
}

Outro ponto q creio q seria interessante para se fazer em um código em C é a declaração dos protótipos das funções usadas no código no início do mesmo. Segundo a Victorine Viviane Mizhari, todo bom programador declara os protótipos das funções q são usadas em um código. Isso é muito útil quando mais de uma pessoa trabalha em um mesmo código

Seria algo q recomendo já ir colocando em prática, até por ser uma boa prática de programação

 

Outro ponto q vai ser muito útil até para já ser posto em prática nesse código q você postou e em qualquer projeto q venha a fazer é procurar manter limpo o stdin, ou seja, evitar q sujeira do buffer venha a atrapalhar futuras leituras via teclado em seu código. Para isso, recomendaria duas funções, entre elas uma q uso com frequência em meus código

Seria elas:

void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}

Ou, essa, que foi criada por um colega aqui do fórum:

void fflush_stdin() {
    char ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

Essas funções, qual achar mais interessante, pode ser chamada após cada leitura do teclado feita pelo scanf

 

Qualquer dúvida é só perguntar.

Obs: Gostei do uso q está fazendo da API do Windows, que, pelo que me disseram, é conhecida com Win32 API😉

Só inda não deu para trabalhar em seu código, desculpa por isso

Forte abraço!

Postado
Em 04/11/2018 às 12:46, s4lezardv1A disse:

Desculpe Ansic, o que eu poderia melhorar nessa parte de estrutura do codigo? E porque não estou conseguindo printar quando eu adiciono no final?No inserir inicio da tudo certo..

A minha única observação e com relação alto acoplamento da função. Ao meu ver, fica mais fácil visializar a tarefa quando está bem divida entre funções. É benéfico tanto para design quanto é para manutenção, Depuração e otimização do código, nesse aspecto você só tem a ganhar.

 

Já fiz muitos exemplos desses por aqui, mas cada um faz como quiser e C o unica jeito errado é aquele que não funciona rsrsrsr. Vou demostrar, mais um vez, o nosso jeito:

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct Elemento
{   char              pais[10];
    struct Elemento * proximo;

} TIPO_ELEMENTO;

 

TIPO_ELEMENTO * elemento_novo( TIPO_ELEMENTO * fonte )
{   TIPO_ELEMENTO * novo= malloc( sizeof (TIPO_ELEMENTO) );
    
    if( NULL == novo )perror( "[elemento_novo] Memoria Insuficiente" );
    else
    {   (* novo)= (* fonte);
    }
    return novo;
}

 

TIPO_ELEMENTO * criar_cadeia( TIPO_ELEMENTO * lista )
{   if( NULL == lista )
    {   TIPO_ELEMENTO tmp= { "#", NULL };
        return elemento_novo(& tmp);
    }
    else
    {   printf("Cadeia ja foi criada\n\n");
    }
    printf( "\n\n\n\n\t\t\t\tPressione ENTER para continuar" );
    system( "PAUSE > NULL" );
    return lista;
}

 

  

void inserir_final( TIPO_ELEMENTO * lista, TIPO_ELEMENTO * novo )
{   while( NULL != lista->proximo )
    {   lista= lista->proximo; 
    }
    lista->proximo= novo;
}

 

void button_inserir_final( TIPO_ELEMENTO * lista )
{   SetConsoleTitle( "INSERIR FINAL" );
   /* pode ser também: system( "TITLE INSERIR FINAL" ); */
   
    if( (NULL == lista)||('#' != lista->pais[0]) )
    {    printf( "%s", "\n\nCrie o encadeamento primeiro" );
    }
    else
    {   TIPO_ELEMENTO tmp= { "", NULL };

        printf( "Digite o pais: " );
        scanf( "%9[^\n]", tmp.pais );
        
        setbuf( stdin, NULL );
        
        inserir_final( lista, elemento_novo(& tmp) );
    }
}

 

int main( void )
{   /* $$ Realizar teste das funções */
    /* 1$ Declara alguns tipos para testar a função inserir_final */
    puts( "Testando o metodo inserir_final" );
    TIPO_ELEMENTO item5= { "Peru", NULL };     /*< elemento */
    TIPO_ELEMENTO item4= { "Chile", NULL };    /*< elemento */
    TIPO_ELEMENTO item3= { "Colombia", NULL }; /*< elemento */
    TIPO_ELEMENTO item2= { "Paraguai", NULL }; /*< elemento */
    TIPO_ELEMENTO item1= { "Brasil", NULL };   /*< elemento */
    TIPO_ELEMENTO itemx= { "#", NULL };      /*< é a cabeça da lista */
    
    /* 1$ Inserir no final */
    inserir_final(&itemx, (& item1) );
    inserir_final(&itemx, (& item2) );
    inserir_final(&itemx, (& item3) );
    inserir_final(&itemx, (& item4) );
    inserir_final(&itemx, (& item5) );
    
    /* 1$ Imprimindo teste */
    TIPO_ELEMENTO * index= (& itemx);
    
    while( NULL != index )
    {   printf( "%s ", index->pais);
        index= index->proximo; 
    }
    
    /* 2$ função button_inserir_final */
    puts( "Testando o metodo button_inserir_final" );
    
    /* 2$ Inserir no final */
    TIPO_ELEMENTO * minha_lista= criar_cadeia( NULL );
    
    button_inserir_final( minha_lista );
    button_inserir_final( minha_lista );
    button_inserir_final( minha_lista );
    
    /* 2$ Imprimindo teste */
    TIPO_ELEMENTO * minha_index= minha_lista;
    
    while( NULL !=  minha_index )
    {   printf( "%s ",  minha_index->pais);
         minha_index=  minha_index->proximo; 
    }
    return 0;
}

Obrigado

Postado
Em 05/11/2018 às 23:12, AnsiC disse:

A minha única observação e com relação alto acoplamento da função. Ao meu ver, fica mais fácil visializar a tarefa quando está bem divida entre funções. É benéfico tanto para design quanto é para manutenção, Depuração e otimização do código, nesse aspecto você só tem a ganhar.

 

Já fiz muitos exemplos desses por aqui, mas cada um faz como quiser e C o unica jeito errado é aquele que não funciona rsrsrsr. Vou demostrar, mais um vez, o nosso jeito:


#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct Elemento
{   char              pais[10];
    struct Elemento * proximo;

} TIPO_ELEMENTO;

 


TIPO_ELEMENTO * elemento_novo( TIPO_ELEMENTO * fonte )
{   TIPO_ELEMENTO * novo= malloc( sizeof (TIPO_ELEMENTO) );
    
    if( NULL == novo )perror( "[elemento_novo] Memoria Insuficiente" );
    else
    {   (* novo)= (* fonte);
    }
    return novo;
}

 


TIPO_ELEMENTO * criar_cadeia( TIPO_ELEMENTO * lista )
{   if( NULL == lista )
    {   TIPO_ELEMENTO tmp= { "#", NULL };
        return elemento_novo(& tmp);
    }
    else
    {   printf("Cadeia ja foi criada\n\n");
    }
    printf( "\n\n\n\n\t\t\t\tPressione ENTER para continuar" );
    system( "PAUSE > NULL" );
    return lista;
}

 

  


void inserir_final( TIPO_ELEMENTO * lista, TIPO_ELEMENTO * novo )
{   while( NULL != lista->proximo )
    {   lista= lista->proximo; 
    }
    lista->proximo= novo;
}

 


void button_inserir_final( TIPO_ELEMENTO * lista )
{   SetConsoleTitle( "INSERIR FINAL" );
   /* pode ser também: system( "TITLE INSERIR FINAL" ); */
   
    if( (NULL == lista)||('#' != lista->pais[0]) )
    {    printf( "%s", "\n\nCrie o encadeamento primeiro" );
    }
    else
    {   TIPO_ELEMENTO tmp= { "", NULL };

        printf( "Digite o pais: " );
        scanf( "%9[^\n]", tmp.pais );
        
        setbuf( stdin, NULL );
        
        inserir_final( lista, elemento_novo(& tmp) );
    }
}

 


int main( void )
{   /* $$ Realizar teste das funções */
    /* 1$ Declara alguns tipos para testar a função inserir_final */
    puts( "Testando o metodo inserir_final" );
    TIPO_ELEMENTO item5= { "Peru", NULL };     /*< elemento */
    TIPO_ELEMENTO item4= { "Chile", NULL };    /*< elemento */
    TIPO_ELEMENTO item3= { "Colombia", NULL }; /*< elemento */
    TIPO_ELEMENTO item2= { "Paraguai", NULL }; /*< elemento */
    TIPO_ELEMENTO item1= { "Brasil", NULL };   /*< elemento */
    TIPO_ELEMENTO itemx= { "#", NULL };      /*< é a cabeça da lista */
    
    /* 1$ Inserir no final */
    inserir_final(&itemx, (& item1) );
    inserir_final(&itemx, (& item2) );
    inserir_final(&itemx, (& item3) );
    inserir_final(&itemx, (& item4) );
    inserir_final(&itemx, (& item5) );
    
    /* 1$ Imprimindo teste */
    TIPO_ELEMENTO * index= (& itemx);
    
    while( NULL != index )
    {   printf( "%s ", index->pais);
        index= index->proximo; 
    }
    
    /* 2$ função button_inserir_final */
    puts( "Testando o metodo button_inserir_final" );
    
    /* 2$ Inserir no final */
    TIPO_ELEMENTO * minha_lista= criar_cadeia( NULL );
    
    button_inserir_final( minha_lista );
    button_inserir_final( minha_lista );
    button_inserir_final( minha_lista );
    
    /* 2$ Imprimindo teste */
    TIPO_ELEMENTO * minha_index= minha_lista;
    
    while( NULL !=  minha_index )
    {   printf( "%s ",  minha_index->pais);
         minha_index=  minha_index->proximo; 
    }
    return 0;
}

Obrigado

Show Ansic, Identação , organização perfeita!Vou estudar seu codigo. Consegui implementar a lista, mas estou procurando outras formas tambem.

adicionado 3 minutos depois
Em 04/11/2018 às 21:42, giu_d disse:

Olá @s4lezardv1A Desculpa a demora em responder. É q tive q me ausentar um pouco

Para mostrar de maneira mais simples o que estou querendo passar com relação ao comentário q fiz acima, apenas montei um pequeno código q ilustra de maneira prática essa lógica. As funções do código abaixo eu peguei do tutorial q te passei acima

Creio q com esse código vai entender a lógica q comentei acima, com respeito a retornar a lista atualizada com as alterações feitas

Segue o código:


#include <stdio.h>
#include <stdlib.h>

struct lista {
    int info;
    struct lista* prox;
};

typedef struct lista Lista;

/* Declaração dos protótipos das funções */
Lista *inicializa(void);
void imprime(Lista *);
Lista *retira(Lista *, int);
void libera(Lista *);
Lista *ordena(Lista *);

/* função de inicialização: retorna uma lista vazia */
Lista* inicializa (void)
{
    return NULL;
}

/* inserção no início: retorna a lista atualizada */
Lista* insere (Lista* l, int i)
{
    Lista* novo = malloc(sizeof(Lista));
    novo->info = i;
    novo->prox = l;
    return novo;
}


/* função imprime: imprime valores dos elementos */
void imprime (Lista* l)
{
    Lista* p; /* variável auxiliar para percorrer a lista */
    for (p = l; p != NULL; p = p->prox)
        printf("info = %d\n", p->info);

    printf("\n");
}

Lista *ordena(Lista *l) {

    Lista *p = l; /* ponteiro para percorrer a lista*/
    Lista *t;
    int temp;

    while (p != NULL) {
        t = p->prox;
        while (t != NULL) {
            if (t->info < p->info) {
                temp = p->info;
                p->info = t->info;
                t->info = temp;
            }
            t = t->prox;
        }
        p = p->prox;
    }

    return l;
}


/* função retira: retira elemento da lista */
Lista* retira (Lista* l, int v) {
    Lista* ant = NULL; /* ponteiro para elemento anterior */
    Lista* p = l; /* ponteiro para percorrer a lista*/
    /* procura elemento na lista, guardando anterior */
    while (p != NULL && p->info != v) {
        ant = p;
        p = p->prox;
    }
    /* verifica se achou elemento */
    if (p == NULL)
        return l; /* não achou: retorna lista original */
    /* retira elemento */
    if (ant == NULL) {
        /* retira elemento do inicio */
        l = p->prox;
    }
    else {
        /* retira elemento do meio da lista */
        ant->prox = p->prox;
    }
    free(p);

    return l;
}


void libera (Lista* l)
{
    Lista* p = l;
    while (p != NULL) {
        Lista* t = p->prox; /* guarda referência para o próximo elemento */
        free(p); /* libera a memória apontada por p */
        p = t; /* faz p apontar para o próximo */
    }
}

int main (void) {

    Lista* l; /* declara uma lista não iniciada */
    l = inicializa(); /* inicia lista vazia */
    l = insere(l, 23); /* insere na lista o elemento 23 */
    l = insere(l, 45); /* insere na lista o elemento 45 */
    l = insere(l, 56); /* insere na lista o elemento 56 */
    imprime(l);

    l = ordena(l); /* ordena a lista em ordem crescente */
    imprime(l);

    l = insere(l, 78); /* insere na lista o elemento 78 */
    imprime(l);
    l = retira(l, 78);
    imprime(l);
    l = retira(l, 45);
    imprime(l);
    
    libera(l);
    
    return 0;
}

Outro ponto q creio q seria interessante para se fazer em um código em C é a declaração dos protótipos das funções usadas no código no início do mesmo. Segundo a Victorine Viviane Mizhari, todo bom programador declara os protótipos das funções q são usadas em um código. Isso é muito útil quando mais de uma pessoa trabalha em um mesmo código

Seria algo q recomendo já ir colocando em prática, até por ser uma boa prática de programação

 

Outro ponto q vai ser muito útil até para já ser posto em prática nesse código q você postou e em qualquer projeto q venha a fazer é procurar manter limpo o stdin, ou seja, evitar q sujeira do buffer venha a atrapalhar futuras leituras via teclado em seu código. Para isso, recomendaria duas funções, entre elas uma q uso com frequência em meus código

Seria elas:


void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}

Ou, essa, que foi criada por um colega aqui do fórum:


void fflush_stdin() {
    char ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

Essas funções, qual achar mais interessante, pode ser chamada após cada leitura do teclado feita pelo scanf

 

Qualquer dúvida é só perguntar.

Obs: Gostei do uso q está fazendo da API do Windows, que, pelo que me disseram, é conhecida com Win32 API😉

Só inda não deu para trabalhar em seu código, desculpa por isso

Forte abraço!

Muito obrigado, vou seguir suas recomendações. Tem uma função que me foi passada: a fflush(stdin); funciona direto, é a mesma né? Estou trabalhando nessa parte da api. Daqui algumas semanas eu posto um codigo bem legal que montei.

Postado

@s4lezardv1A Olá. Não é nada recomendável o uso do fflush(stdin);. Nós, aqui do fórum, não usamos essa função dessa forma (Para limpar o buffer do teclado). Recomendo o uso de uma das funções que passei acima. Uma delas até foi criada por um colega daqui do fórum

 

Obs: Já vou aproveitar e fazer uma pergunta: É muito avançado o uso da API do Windows? Para quem está começando a trabalhar com interface gráfica, assim como eu, aprender sobre essa Win32 API é recomendável? 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...