pilhas em c [RESOLVIDO]

1. pilhas em c [RESOLVIDO]

Daniel
danielcrvg

(usa Slackware)

Enviado em 30/03/2013 - 11:59h

Galera eu to estudando estrutura de dados na faculdade, porem meu professor nao é muito pratico. Consegui este codigo e dei uma implementada, mas fiz os comentarios onde no codigo eu nao consegui entender. O codigo ta rodando tranquilo, estou usando NetBeans no slackware. So que minhas duvidas sao apenas para fins didaticos mesmo.

Se puderem me ajudar fico agradecido.




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

using namespace std;

typedef struct pilha {
int numero;
pilha * proximo;
};

void inserir(pilha **top) {
pilha * novo;
//ponteiro que aponta para novo elemento inserido.
//Mas, por que eu tenho que utilizar ponteiro para apontar para o valor inserido?

//Como o dado sera inserido pelo usuario, precisa alocar memoria para o ponteiro.
novo = (pilha *) malloc(sizeof(pilha));
// Traduzindo o comando, Eu entendi desta forma: novo recebera(=) um ponteiro do tipo pilha(pilha *), alocando memoria atraves do comando malloc, no tamanho de(sizeof()).
// Nao entendi o porque é colocado o (pilha) novamente, se o tipo ja foi estipulado antes.

if (novo == NULL) {
printf("\nERRO!! Sem memoria\n");
exit(1);
} else {

printf("Informe o numero: \n");
scanf("%d", &novo->numero); //Coloca dentro da variavel numero estipulada na estrutura.


//Aqui abaixo eu nao consegui entender direito a mecanica.
//Ele diz que *top refere-se ao TOPO da pilha, mas nao entendi aonde no codigo que é estipulado isto.

if (*top == NULL) { //Se o topo estiver vazio, ou seja, nao tem elementos na pilha.
novo->proximo = NULL; // O ponteiro proximo aponta pra nada.
} else {
novo->proximo = *top; //Se o topo nao estiver vazio, o ponteiro proximo aponta para topo.
}
*top = novo; //e o topo recebe o novo elemento.

}

}

void listar(pilha *top) {
pilha * aux;

if (top == NULL) { //Aqui a mesma coisa, nao entendi onde ele diz que top refere-se ao topo.
printf("\nPilha vazia!!\n");
} else {
aux = top;
while (aux != NULL) {
printf("%d \n", aux->numero);
aux = aux->proximo;
}
}
}

int main(int argc, char** argv) {

pilha * topo = NULL;
int op = 0;

do {
printf("Digite a OP (1-inserir, 2-listar, 3-PARAR) \n");
scanf("%d", &op);

switch (op) {

case 1:
inserir(&topo);
break;

case 2:
printf("\nLISTA COMPLETA: \n");
listar(topo);
break;

default:
break;
}

} while (op != 3);

return 0;
}





  


2. MELHOR RESPOSTA

Perfil removido
removido

(usa Nenhuma)

Enviado em 31/03/2013 - 11:02h

    if (novo == NULL) {
printf("\nERRO!! Sem memoria\n");
exit(1);


Se a variável que recebeu a estrutura criada pelo malloc() for um NULL, é porque o espaço não foi alocado. Caso contrário segue ELSE:

    } else {

printf("Informe o numero: \n");
scanf("%d", &novo->numero); //Coloca dentro da variavel numero estipulada na estrutura.


Até aqui tudo bem, ele recebe um valor e armazena.

        //Aqui abaixo eu nao consegui entender direito a mecanica.
//Ele diz que *top refere-se ao TOPO da pilha, mas nao entendi aonde no codigo que é estipulado isto.

if (*top == NULL) { //Se o topo estiver vazio, ou seja, nao tem elementos na pilha.
novo->proximo = NULL; // O ponteiro proximo aponta pra nada.


O caso em que a função recebeu um NULL foi no início do programa, quando a pilha estava vazia. Perceba que é como se parecesse que esse NULL se desloca ao ser atribuído ao NOVO elemento criado. Se o topo da pilha não estiver vazio, ou seja, com NULL, segue ELSE:

        } else {
novo->proximo = *top; //Se o topo nao estiver vazio, o ponteiro proximo aponta para topo.
}


Imagine a pilha como um monte de ganchos um pendurado nos outros num prego. O que o programa faz é retirar o gancho que está no prego, colocar um gancho novo nesse prego e recolocar o gancho retirado nesse gancho novo. O prego é o topo da pilha. O gancho novo é o novo elemento alocado e os outros ganchos são os elementos que já estavam. Prego vazio é análogo à uma pilha vazia. O gancho que está mais abaixo não possui coisa alguma ligada, está com um NULL ao final. Sabemos apenas onde é o topo e por isso colocam-se por ali os elementos.

Lembrando que apenas se falou da operação PUSH, que é colocar elementos na pilha. Nada foi falado de POP, que é retirar um elemento do topo da pilha. Inclusive era bom fazer uma função prá desalocar toda a memória que ficou pendurada com os MALLOCs().

        *top = novo; //e o topo recebe o novo elemento.

}


E aqui o elemento novo é colocado no topo da pilha. Se a pilha estava vazia, ele entra agora com NULL que já foi colocado ao final lá em cima. Se não estiver, o elemento que estava no topo foi retirado do topo e colocada sua referência nesse novo que chega, conforme foi feito lá em cima.



3. Re: pilhas em c [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 31/03/2013 - 00:39h

danielcrvg escreveu:

Galera eu to estudando estrutura de dados na faculdade, porem meu professor nao é muito pratico. Consegui este codigo e dei uma implementada, mas fiz os comentarios onde no codigo eu nao consegui entender. O codigo ta rodando tranquilo, estou usando NetBeans no slackware. So que minhas duvidas sao apenas para fins didaticos mesmo.

Se puderem me ajudar fico agradecido.



Ah, você é o cara do Backtrack da outra postagem.

Me diz uma coisa, esse código que você conseguiu é em C ou em C++?


4. Re: pilhas em c [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 31/03/2013 - 01:04h

EDIT

void inserir(pilha **top) {
pilha * novo;
//ponteiro que aponta para novo elemento inserido.
//Mas, por que eu tenho que utilizar ponteiro para apontar para o valor inserido?


Essa é confusa: **top é um ponteiro para ponteiro. A função modifica a variável que recebe. Já que isso é feito com ponteiros e o que ela recebe é um ponteiro, então fica sendo um ponteiro para um ponteiro.

    //Como o dado sera inserido pelo usuario, precisa alocar memoria para o ponteiro.
novo = (pilha *) malloc(sizeof(pilha));
// Traduzindo o comando, Eu entendi desta forma: novo recebera(=) um ponteiro do tipo pilha(pilha *), alocando memoria atraves do comando malloc, no tamanho de(sizeof()).
// Nao entendi o porque é colocado o (pilha) novamente, se o tipo ja foi estipulado antes.


Malloc retorna ponteiro tipo void (void *), que é a coisa mais próxima de um tipo de dado neutro. Esse (pilha *) faz conversão desse ponteiro void pro tipo pilha.
Ponteiro void representa um endereço de memória. Ponteiro tipo pilha representa um endereço de memória e diz que ali tem um tipo de dado que deve ser entendido como pilha.

Esse valor será repassado prá alguma variável com esse mesmo tipo de dado.

 

printf("Informe o numero: \n");
scanf("%d", &novo->numero); //Coloca dentro da variavel numero estipulada na estrutura.

//Aqui abaixo eu nao consegui entender direito a mecanica.
//Ele diz que *top refere-se ao TOPO da pilha, mas nao entendi aonde no codigo que é estipulado isto.


Refere-se à função inserir(). Essa variável top, explicada lá em cima, recebe um valor quando a função é executada. A comparação é prá saber se o valor é NULL. Se ela está se referindo ao início da estrutura, então quer dizer que a estrutura está vazia.

Daí o programa avalia o que faz quando isso ocorre, se há algum dado a ser exibido, inserido, eliminado etc.

    if (top == NULL) { //Aqui a mesma coisa, nao entendi onde ele diz que top refere-se ao topo.
printf("\nPilha vazia!!\n");
} else {
aux = top;


Mesma coisa, top é a variável da função. Perceba que na outra função aparece *top ao invés de **top. A finalidade é outra.



5. Re: pilhas em c [RESOLVIDO]

???
gokernel

(usa Linux Mint)

Enviado em 31/03/2013 - 07:29h

o que vou informar não é ligado diretamente a esse asunto(suas duvidas) ...

...

não sei se tambem seu professor ja falou das vantagens/desvantagens do modelo de estrutura de dado ( lista encadeada simples ) com outros modelos ...

VANTAGEM:
01 - facilidade de colocar/retirar um elemento da lista.

DESVANTAGEM:
01 - Consume MUITO MAIS(principalmente se a estrutura base for maior) memória se comparado com o modelo ( array de ponteiro ) ...

02 - É mais "lento"(requer um loop) para ler um elemento se comparado ao modelo com array ( onde pega o index direto ) ... lógico, aqui me refiro a uma lista com muitos elementos ...

Então no futuro quando for planejar um projeto relativamente medio/grande levar em conta essa "vantagem/desvantagem" do modelo de organização de dados.

Creio que essas instruções serão informadas no futuro no seu curso ...

OBS: mas não se preocupe com isso agora .... ISSO FOI APENAS UMA TENTATIVA DE PROGRAMAR A SUA MENTE. ;)

Abraço !


6. Re: pilhas em c [RESOLVIDO]

Daniel
danielcrvg

(usa Slackware)

Enviado em 31/03/2013 - 09:50h

Listeiro 037 escreveu:

danielcrvg escreveu:

Galera eu to estudando estrutura de dados na faculdade, porem meu professor nao é muito pratico. Consegui este codigo e dei uma implementada, mas fiz os comentarios onde no codigo eu nao consegui entender. O codigo ta rodando tranquilo, estou usando NetBeans no slackware. So que minhas duvidas sao apenas para fins didaticos mesmo.

Se puderem me ajudar fico agradecido.



Ah, você é o cara do Backtrack da outra postagem.

Me diz uma coisa, esse código que você conseguiu é em C ou em C++?




é em C(eu acho). ja é a segunda pessoa q pergunta isso. Por que seria c++??


7. Re: pilhas em c [RESOLVIDO]

Daniel
danielcrvg

(usa Slackware)

Enviado em 31/03/2013 - 09:56h

gokernel escreveu:

o que vou informar não é ligado diretamente a esse asunto(suas duvidas) ...

...

não sei se tambem seu professor ja falou das vantagens/desvantagens do modelo de estrutura de dado ( lista encadeada simples ) com outros modelos ...

VANTAGEM:
01 - facilidade de colocar/retirar um elemento da lista.

DESVANTAGEM:
01 - Consume MUITO MAIS(principalmente se a estrutura base for maior) memória se comparado com o modelo ( array de ponteiro ) ...

02 - É mais "lento"(requer um loop) para ler um elemento se comparado ao modelo com array ( onde pega o index direto ) ... lógico, aqui me refiro a uma lista com muitos elementos ...

Então no futuro quando for planejar um projeto relativamente medio/grande levar em conta essa "vantagem/desvantagem" do modelo de organização de dados.

Creio que essas instruções serão informadas no futuro no seu curso ...

OBS: mas não se preocupe com isso agora .... ISSO FOI APENAS UMA TENTATIVA DE PROGRAMAR A SUA MENTE. ;)

Abraço !



nada po, tuudo é valido, muito obrigado. Por em quanto estamos falando de pilha, e proxima aula vai ser implementacao no codigo. So que como eu ja to prevendo que ele nao vai conseguir explicar direito, ja to tentando fazer isto por conta propria.. valeu


8. Re: pilhas em c [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 31/03/2013 - 10:16h

Por causa disto:

using namespace std; 



9. Re: pilhas em c [RESOLVIDO]

Daniel
danielcrvg

(usa Slackware)

Enviado em 31/03/2013 - 10:18h

Listeiro 037 escreveu:

EDIT

void inserir(pilha **top) {
pilha * novo;
//ponteiro que aponta para novo elemento inserido.
//Mas, por que eu tenho que utilizar ponteiro para apontar para o valor inserido?


Essa é confusa: **top é um ponteiro para ponteiro. A função modifica a variável que recebe. Já que isso é feito com ponteiros e o que ela recebe é um ponteiro, então fica sendo um ponteiro para um ponteiro.

    //Como o dado sera inserido pelo usuario, precisa alocar memoria para o ponteiro.
novo = (pilha *) malloc(sizeof(pilha));
// Traduzindo o comando, Eu entendi desta forma: novo recebera(=) um ponteiro do tipo pilha(pilha *), alocando memoria atraves do comando malloc, no tamanho de(sizeof()).
// Nao entendi o porque é colocado o (pilha) novamente, se o tipo ja foi estipulado antes.


Malloc retorna ponteiro tipo void (void *), que é a coisa mais próxima de um tipo de dado neutro. Esse (pilha *) faz conversão desse ponteiro void pro tipo pilha.
Ponteiro void representa um endereço de memória. Ponteiro tipo pilha representa um endereço de memória e diz que ali tem um tipo de dado que deve ser entendido como pilha.

Esse valor será repassado prá alguma variável com esse mesmo tipo de dado.

 

printf("Informe o numero: \n");
scanf("%d", &novo->numero); //Coloca dentro da variavel numero estipulada na estrutura.

//Aqui abaixo eu nao consegui entender direito a mecanica.
//Ele diz que *top refere-se ao TOPO da pilha, mas nao entendi aonde no codigo que é estipulado isto.


Refere-se à função inserir(). Essa variável top, explicada lá em cima, recebe um valor quando a função é executada. A comparação é prá saber se o valor é NULL. Se ela está se referindo ao início da estrutura, então quer dizer que a estrutura está vazia.

Daí o programa avalia o que faz quando isso ocorre, se há algum dado a ser exibido, inserido, eliminado etc.

    if (top == NULL) { //Aqui a mesma coisa, nao entendi onde ele diz que top refere-se ao topo.
printf("\nPilha vazia!!\n");
} else {
aux = top;


Mesma coisa, top é a variável da função. Perceba que na outra função aparece *top ao invés de **top. A finalidade é outra.



tipo assim:

vou chamar a funcao inserir(). e passarei um endereco de variavel (&topo) para ela.
Dentro da funcao main() ele ja esta setado como (pilha * topo = NULL) ou seja, &topo é null.


Dentro da funcao inserir() ele vai comparar.


else {

printf("Informe o numero: \n");
scanf("%d", &novo->numero);

if (*top == NULL) { // Se o *top for NULL, ou seja aquele endereco de variavel &topo for NULL.
novo->proximo = NULL;
} else {
novo->proximo = *top; // Se nao, o ponteiro proximo vai apontar para o topo, mas dentro da funcao main ele sempre é passado como NULL nao??
}
*top = novo; //e o topo recebe o novo elemento.

}


Eu nao to conseguindo vizualizar a insercao neste codigo. Na teoria eu ate consigo, mas dentro deste codigo nao to conseguindo vizualizar.

Na teoria eu entendi assim: Vou inserir o elemento "A", como uma estrutura, que tem uma variavel "int numero" q armazenara o numero inserido, e um ponteiro "* proximo" que apontara para o outro elemento acima dele. Se eu inserir B, o ponteiro (*proximo do elemento A apontara para B). Se eu inserir o elemento C, o ponteiro *proximo de B, apontara para o elemento C....









10. Re: pilhas em c [RESOLVIDO]

Daniel
danielcrvg

(usa Slackware)

Enviado em 31/03/2013 - 10:19h

Listeiro 037 escreveu:

Por causa disto:

using namespace std; 



acho q isso aaparece pq eu to fazendo no NetBeans...


11. Re: pilhas em c [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 31/03/2013 - 10:30h

Ele deve estar usando compilador de C++, porque using não faz parte do C.


12. Re: pilhas em c [RESOLVIDO]

Daniel
danielcrvg

(usa Slackware)

Enviado em 31/03/2013 - 11:36h

humm comecou a dar uma clareada...


o NULL do topo, sempre existira, pq ele realmente nao aponta nada, e sempre fica descolando a medida q elementos forem adicionado, é isso??

EX:

C (* proximo aponta para NULL)

B (* proximo aponta para C)

A (* proximo aponta para B)


Se colocar mais 1 elemento "D" fica:

D (* proximo aponta para NULL)

C (* proximo aponta para D)

B (* proximo aponta para C)

A (* proximo aponta para B)






01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts