Ir ao conteúdo
  • Cadastre-se

C exibir topo da PILHA em C


vagabond1

Posts recomendados

Alguem ai para ajudar no codigo acima?

Preciso elaborar uma função que exiba o topo da pilha e a função deverá imprimir o elemento do topo, mas esta dando erro no codigo

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


struct Pilha {

	int topo; 
	int capa;
	float *pElem;

};

void criarpilha( struct Pilha *p, int c ){

   p->topo = -1;
   p->capa = c;
   p->pElem = (float*) malloc (c * sizeof(float));

}

void pilha_vazia(Pilha* pi) {
    if(pi == NULL || *pi == NULL)
        printf("\n Pilha está vazia!");
    else
        printf("\n Pilha não está vazia!");
}

int push(Pilha* pilha, struct prato p) {
    
    if(pilha == NULL)
        return 0;
        
    struct elemento* aux = (struct elemento*)malloc(sizeof(struct elemento));
    
    if(aux == NULL)
        return 0;
    
    aux->item = p;
    aux->prox = (*pilha);
    
    *pilha = aux; 
    
    return 1;
}

int estacheia ( struct Pilha *p ){

	if (p->topo == p->capa - 1)

		return 1;

	else

		return 0;

}

void empilhar ( struct Pilha *p, float v){

	p->topo++;
	p->pElem [p->topo] = v;

}

float desempilhar ( struct Pilha *p ){

   float aux = p->pElem [p->topo];
   p->topo--;
   return aux;

}

float retornatopo ( struct Pilha *p ){

   return p->pElem [p->topo];

}

int main(){

	struct Pilha minhapilha;
	int capacidade, op;
	float valor;

	printf( "\nCapacidade da pilha? " );
	scanf( "%d", &capacidade );

	criarpilha (&minhapilha, capacidade);

	while( 1 ){ /* loop infinito */

		printf("\n1- empilhar (push)\n");
		printf("2- desempilhar (POP)\n");
		printf("3- Mostrar o topo \n");
		printf("4- sair\n");
		printf("\nopcao? ");
		scanf("%d", &op);

		switch (op){

			case 1: //push

				if( estacheia( &minhapilha ) == 1 )

					printf("\nPILHA CHEIA! \n");

				else {

					printf("\nVALOR? ");
					scanf("%f", &valor);
					empilhar (&minhapilha, valor);

				}
				break;

			case 2: //pop
				if ( estavazia(&minhapilha) == 1 )

					printf( "\nPILHA VAZIA! \n" );

				else{

					valor = desempilhar (&minhapilha);
					printf ( "\n%.1f DESEMPILHADO!\n", valor );

				}
				break;

			case 3: // mostrar o topo
				if ( estavazia (&minhapilha) == 1 )

					printf( "\nPILHA VAZIA!\n" );

				else {

					valor = retornatopo (&minhapilha);
					printf ( "\nTOPO: %.1f\n", valor );

				}
				break;

			case 4: 
				exit(0);

			default: printf( "\nOPCAO INVALIDA! \n" );
		}
	}
	
}

 

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

	if (pi == NULL || *pi == NULL)

A segunda condição não faz sentido. (*pi) é uma struct.

 

Você tem uma função push() perdida no código. 

 

E faltam uns struct em declarações de pilha.

 

Ao invés de declarar 

struct Pilha {

	int topo;
	int capa;
	float* pElem;

};

Se acostume a declarar 

typedef struct // (a)
{
	int topo;
	int capa;
	float* pElem;
}	Pilha;

// ou mesmo

struct _pilha // (b)
{
	int topo;
	int capa;
	float* pElem;
};
typedef struct _pilha Pilha;

Assim não precisa ficar repetindo struct em todo lugar. E se não precisa repetir não vai esquecer ;) 

 

typedef cria um alias, um sinônimo.

 

O exemplo (b) é mais seguro porque pode ainda usar referências a _pilha dentro da struct porque o nome já é conhecido, Se não precisa, o caso (a) é mais legível.

 

Em pilhas os métodos push() pop() e top() são consagrados. Podia manter

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Em 05/06/2020 às 21:34, arfneto disse:

	if (pi == NULL || *pi == NULL)

A segunda condição não faz sentido. (*pi) é uma struct.

 

Você tem uma função push() perdida no código. 

 

E faltam uns struct em declarações de pilha.

 

Ao invés de declarar 


struct Pilha {

	int topo;
	int capa;
	float* pElem;

};

Se acostume a declarar 


typedef struct // (a)
{
	int topo;
	int capa;
	float* pElem;
}	Pilha;

// ou mesmo

struct _pilha // (b)
{
	int topo;
	int capa;
	float* pElem;
};
typedef struct _pilha Pilha;

Assim não precisa ficar repetindo struct em todo lugar. E se não precisa repetir não vai esquecer ;) 

 

typedef cria um alias, um sinônimo.

 

O exemplo (b) é mais seguro porque pode ainda usar referências a _pilha dentro da struct porque o nome já é conhecido, Se não precisa, o caso (a) é mais legível.

 

Em pilhas os métodos push() pop() e top() são consagrados. Podia manter

Realmene acrescentar a nova declaração resolveu um problema e alterar o (*pi) tambem, mas não estou entendo estes erros, li todos eles mas mesmo alterando não resolve os problemas.

 

Outra coisa seria no int main, creio que não faz sentido declarar dentro da case o pilha_vazio sendo que esta sendo declarado na struct, certo?

 

dfff.JPG

sdfd.JPG

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

image.png.0a7a13965ee5228046814eaf64d9d300.png

 

Você tem um livro sobre C? Qual? Como aprende os comandos, os conceitos?

 

Que pretende escrevendo struct p? Você entende inglês? Se não entende, pode conseguir um compilador que gere mensagens em português?

 

Lá diz que o tipo para o parâmetro 2 está incompleto aí vai lá e lê struct p... Mas que p#$$a de struct? Qual seria o nome da struct? E no parâmetro anterior você escreveu struct* Pilha pilha.

 

Como acha que em um caso precisa do  tipo e no outro não, na mesma linha?

 

E essa não é a função que nem usa no programa? Porque não apagou isso?

 

Você escreveu o programa todo ou foi copiando de lugares?

 

Poste o programa todo e a lista de erros toda e não esses trechos de imagens. Ajude os outros a ajudarem você.

 

 

 

 

 

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@arfneto apos tentar bastante consegui dessa forma:

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

struct prato {
  char cor[50];
};

struct elemento {
  struct prato item;
  struct elemento *prox;
};

typedef struct elemento* Pilha;

Pilha* cria_pilha() {
    Pilha* pi = (Pilha*)malloc(sizeof(Pilha));
   
    if(pi != NULL)
        *pi = NULL;
       
    return pi;
}

int recupera_tamanho_pilha(Pilha* pi) {
   
    if(pi == NULL)
        return 0;
       
    int tamanho = 0;
    struct elemento* item = *pi;
    while(item != NULL) {
        tamanho++;
        item = item->prox;
    }
   
    return tamanho;
}

void pilha_vazia(Pilha* pi) {
    if(pi == NULL || *pi == NULL)
        printf("\n Pilha está vazia!");
    else
        printf("\n Pilha não está vazia!");
}

int push(Pilha* pilha, struct prato p) {
   
    if(pilha == NULL)
        return 0;
       
    struct elemento* aux = (struct elemento*)malloc(sizeof(struct elemento));
   
    if(aux == NULL)
        return 0;
   
    aux->item = p;
    aux->prox = (*pilha); //TOPO DA PILHA
   
    *pilha = aux; //Novo elemento passa a ser o primeiro da pilha
   
    return 1;
}


imprime(Pilha* pi){
    struct elemento* item = *pi;

    printf("\n O ultimo  item e  %s", item->item);
   
}

void main()
{
    Pilha *pilha;
   
    pilha = cria_pilha();
   
    printf("\n Tamanho da pilha: %d", recupera_tamanho_pilha(pilha));
   
    pilha_vazia(pilha);
   
    struct prato p;
    strcpy(p.cor, "Azul");
    push(pilha, p);
   
    strcpy(p.cor, "Verde");
    push(pilha, p);  
     strcpy(p.cor, "rosa ");
    push(pilha, p);
   
    printf("\n Tamanho da pilha: %d", recupera_tamanho_pilha(pilha));
    imprime(pilha)  ;
}

O outro codigo consegui fazer executar:

 

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


typedef struct Pilha {

	int topo; 
	int capa;
	float *pElem;

};

void criarpilha( struct Pilha *p, int c ){

   p->topo = -1;
   p->capa = c;
   p->pElem = (float*) malloc (c * sizeof(float));

}

int estavazia(struct Pilha* p) {
    return (p->topo < 0);
}

int estacheia ( struct Pilha *p ){

	if (p->topo == p->capa - 1)

		return 1;

	else

		return 0;

}

void empilhar ( struct Pilha *p, float v){

	p->topo++;
	p->pElem [p->topo] = v;

}

float desempilhar ( struct Pilha *p ){

   float aux = p->pElem [p->topo];
   p->topo--;
   return aux;

}

float retornatopo ( struct Pilha *p ){

   return p->pElem [p->topo];

}

int main(){

	struct Pilha minhapilha;
	int capacidade, op;
	float valor;

	printf( "\nCapacidade da pilha? " );
	scanf( "%d", &capacidade );

	criarpilha (&minhapilha, capacidade);

	while( 1 ){ /* loop infinito */

		printf("\n1- empilhar (push)\n");
		printf("2- desempilhar (POP)\n");
		printf("3- Mostrar o topo \n");
		printf("4- sair\n");
		printf("\nopcao? ");
		scanf("%d", &op);

		switch (op){

			case 1: //push

				if( estacheia( &minhapilha ) == 1 )

					printf("\nPILHA CHEIA! \n");

				else {

					printf("\nVALOR? ");
					scanf("%f", &valor);
					empilhar (&minhapilha, valor);

				}
				break;

			case 2: //pop
				if ( estavazia(&minhapilha) == 1 )

					printf( "\nPILHA VAZIA! \n" );

				else{

					valor = desempilhar (&minhapilha);
					printf ( "\n%.1f DESEMPILHADO!\n", valor );

				}
				break;

			case 3: // mostrar o topo
				if ( estavazia (&minhapilha) == 1 )

					printf( "\nPILHA VAZIA!\n" );

				else {

					valor = retornatopo (&minhapilha);
					printf ( "\nTOPO: %.1f\n", valor );

				}
				break;

			case 4: 
				exit(0);

			default: printf( "\nOPCAO INVALIDA! \n" );
		}
	}
	
}

Mas tentei implementar as funções do segundo codigo no primeiro e sem resultado, então decidi fazer de outra forma

Link para o comentário
Compartilhar em outros sites

23 minutos atrás, vagabond1 disse:

Mas tentei implementar as funções do segundo codigo no primeiro e sem resultado, então decidi fazer de outra forma

 

Mas qual foi o problema?

 

Não sei se entendi a razão de você escrever assim os dados

 

Em especial :

int recupera_tamanho_pilha(Pilha* pi) {
   
    if(pi == NULL)
        return 0;
       
    int tamanho = 0;
    struct elemento* item = *pi;
    while(item != NULL) {
        tamanho++;
        item = item->prox;
    }
   
    return tamanho;
}

Mas se

  • foi você que escreveu a pilha
  • toda inserção e remoção ocorre através de suas rotinas

Porque precisa que uma função que percorre a pilha para recuperar o tamanho?

 

Se usou push() porque não pop() e top(0 ou peek() que são os nomes consagrados para essas funções?

O primeiro caso empilha 'prato'que é um char de 50, alocando um a um?

O segundo empilha float alocando um vetor de float?

 

O que está tentando fazer?

 

Veja essa possível declaração:

struct prato
{
	char cor[50];
};

struct elemento
{
	struct prato*    item;
	struct elemento* prox;
};
typedef struct elemento Elemento;

struct pilha
{
	int         capacidade;
	int         emUso;
	Elemento*   p;
};
typedef struct pilha Pilha;

Esse é o normal.

 

Notas:

  • Em geral você não define typedef só do ponteiro. Se vai usar só um define só o da estrutura
  • Declare capacidade e tamanho DENTRO de cada pilha, assim você pode ter várias pilhas de várias coisas dentro do mesmo programa. E fica TUDO mais fácil
  • A pilha tem um endereço para um elemento. Só isso.
  • Um elemento em geral é um ponteiro para char, ou void. porque assim ao mudar de conteúdo você não precisa nem compilar a parte do programa que mexe com a pilha. Por isso essas estruturas são ditas abstratas. ADT.
  • essas estruturas tem métodos consagrados. Não precisa inventar nada. Basta ver as pilhas em outras linguagens ou na literatura. E as filas, árvores, mapas, árvores, tries e tal. Tudo igual.

Tem um enunciado objetivo?

Um problema objectivo que fez você desistir?

 

Link para o comentário
Compartilhar em outros sites

@arfneto Tem sim,

Esse enunciado que falei, tem que ser feito baseado no exemplo dado em aula

O professor não aceita de outra forma as funções do struct e pilha

A unica coisa que pediu para criarmos com liberdade é função do void main/int main para exeibir e imprimir o topo da pilha

Por isso que o segundo codigo não conta para a resolução do problema, estou me baseando nesse outro codigo

Link para o comentário
Compartilhar em outros sites

@arfneto Entendi amigo, minha dificuldade esta sendo essa de mudar entende?

int main(){

	struct Pilha minhapilha;
	int capacidade, op;
	float valor;

	printf( "\nCapacidade da pilha? " );
	scanf( "%d", &capacidade );

	criarpilha (&minhapilha, capacidade);

	while( 1 ){ /* loop infinito */

		printf("\n1- empilhar (push)\n");
		printf("2- desempilhar (POP)\n");
		printf("3- Mostrar o topo \n");
		printf("4- sair\n");
		printf("\nopcao? ");
		scanf("%d", &op);

		switch (op){

			case 1: //push

				if( estacheia( &minhapilha ) == 1 )

					printf("\nPILHA CHEIA! \n");

				else {

					printf("\nVALOR? ");
					scanf("%f", &valor);
					empilhar (&minhapilha, valor);

				}
				break;

			case 2: //pop
				if ( estavazia(&minhapilha) == 1 )

					printf( "\nPILHA VAZIA! \n" );

				else{

					valor = desempilhar (&minhapilha);
					printf ( "\n%.1f DESEMPILHADO!\n", valor );

				}
				break;

			case 3: // mostrar o topo
				if ( estavazia (&minhapilha) == 1 )

					printf( "\nPILHA VAZIA!\n" );

				else {

					valor = retornatopo (&minhapilha);
					printf ( "\nTOPO: %.1f\n", valor );

				}
				break;

			case 4: 
				exit(0);

			default: printf( "\nOPCAO INVALIDA! \n" );
		}
	}
	
}

E no "case 3" onde define o topo e se a pilha esta vazia que não consigo definer pelo:

void pilha_vazia(Pilha* pi) {
    if(pi == NULL || *pi == NULL)
        printf("\n Pilha está vazia!");
    else
        printf("\n Pilha não está vazia!");
}

int push(Pilha* pilha, struct prato p) {
   
    if(pilha == NULL)
        return 0;
       
    struct elemento* aux = (struct elemento*)malloc(sizeof(struct elemento));
   
    if(aux == NULL)
        return 0;
   
    aux->item = p;
    aux->prox = (*pilha); //TOPO DA PILHA
   
    *pilha = aux; //Novo elemento passa a ser o primeiro da pilha
   
    return 1;
}

 

Link para o comentário
Compartilhar em outros sites

2 minutos atrás, vagabond1 disse:

Entendi, um colega me ajudou e deu certo

 

Bom que funcionou! 🥇

 

Essas estruturas são pensadas como abstratas. Se você declarar do jeito simples como te falei, criar uma pilha seria algo assim

Pilha* cria_pilha(int capacidade)
{
    Pilha* pi = (Pilha*)malloc(sizeof(Pilha));
    pi->capacidade = capacidade;
    pi->emUso = 0;
    pi->p == NULL;
    return pi;
};  // cria_pilha()

E você poderia usar do jeito fácil:

#define _CRT_SECURE_NO_WARNINGS

#include "stdio.h"
#include "stdlib.h"

#include "header.h"

int main()
{
    Pilha* p1 = cria_pilha(200);
    Pilha  pratos = *cria_pilha(30);
    if (pilha_vazia(p1)) printf("pilha 1 vazia\n");
    if (pilha_vazia(&pratos)) printf("pilha 'pratos' vazia\n");
	return 0;
};	// main()

Pilha*  cria_pilha(int capacidade)
{
    Pilha* pi = (Pilha*)malloc(sizeof(Pilha));
    pi->capacidade = capacidade;
    pi->emUso = 0;
    pi->p = NULL;
    return pi;
};  // cria_pilha()

int      pilha_vazia(Pilha* p)
{
return p->emUso == 0;
};  // pilha_vazia()

Quando você cria a pilha já declara o tamanho e ela já é criada vazia. E pode declarar logo um vetor delas se precisar

pilha 1 vazia
pilha 'pratos' vazia

 

Link para o comentário
Compartilhar em outros sites

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...