Gestione di una pila tramite lista

di il
4 risposte

Gestione di una pila tramite lista

Salve ragazzi,

sto perdendo la testa su un programma che secondo me è tanto difficile quanto inutile..

Allora, dovevo creare un programma per la gestione di una Pila tramite una linked list (e ci sono riuscito), successivamente ho dovuto creare la stessa gestione con il nodo sentinella (e pure ci sono riuscito) e per finire devo creare lo stesso identico programma mediante l'uso di una lista generica..

Io ho scritto il programma ma mi da quattro errori sui vari cast:
#include <stdio.h>
#include <stdlib.h>

typedef struct {
        char c;
        } ELEMENT;

void *crealista();
void ins_nodo(short len, ELEMENT dato, void *head);
void elim_nodo(void *head);

void main()       
{
     
     struct pila {
          ELEMENT info;
          struct pila *p_next;
          };
       ELEMENT dato;
       struct pila *head, *punt;
       short scelta=1, elem=0, sentinella=0, len;
       
       head=(struct pila *)crealista(); //creo il nodo sentinella
       head=calloc(1,sizeof(struct pila));
       
       len=sizeof(ELEMENT);
       
       while(scelta!=0) //entro nel menu..
       {
           system("cls");
           printf(" ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n");
           printf(" º Programma per la GESTIONE DI UNA PILA TRAMITE LISTA º\n");
           printf(" ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n");
           
           if(elem>0)
           {
               printf("\n   Ecco la tua pila:\n\n"); //visualizzo la pila
               punt=head;
               printf("\t ÉÍÍÍ»\n");
               sentinella=0;
               while(punt->p_next!=NULL)
               {
                   if(sentinella==1) printf("\t º %c º\n",punt->info.c); 
                   sentinella=1;                 
                   punt=punt->p_next;
               }
               printf("\t º %c º\n",punt->info.c); 
               printf("\t ÈÍÍͼ\n");
           }
           else printf("\n   La PILA e' attualmente vuota..\n"); //se la pila è vuota..
           
           puts("");
           //menù
           printf(" ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n");
           printf(" º ---> 1 per aggiungere un elemento alla PILA º\n");
           printf(" º ---> 2 per eliminare un elemento dalla PILA º\n");
           printf(" º ---> 3 per uscire dal programma...          º\n");
           printf(" ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n");
           
           printf("\n Scelta: "); fflush(stdin); scanf("%d",&scelta);
           
           if(scelta==1) //se scelgo 1..
           {
               do{
                   printf("\n Inserisci il carattere da inserire nella PILA: "); fflush(stdin); scanf("%c",&dato.c);
                   if(dato.c=='\n') printf(" ---> ERRORE: Il carattere INVIO non e' ammesso nella PILA!\n");
                 }while(dato.c=='\n'); //se inserico INVIO non mi ripete l'inserimento..
                           
                   ins_nodo(len,dato,head);
                   printf("\n Elemento inserito!\n\n");
                   elem++;

           }
           
           if(scelta==2) //se scelgo 2..
           {
               if(elem==0) printf("\n La tua pila e' VUOTA!!\n"); //se la pila è gia vuota..
               else
               {
                   elim_nodo(head);
                   elem--;
                   printf("\n Elemento eliminato!!\n"); //altrimenti effettuo eliminazione in testa..
               }
           }                   
                                
            printf("\n\n"); system("pause");
       }

       
}

void *crealista()
{
       struct pila {
          ELEMENT info;
          struct pila *p_next;
          };
          
       struct pila *testa;
       testa=NULL;
       return testa;
}

void ins_nodo(short len, ELEMENT dato, void *head)
{
     struct pila {
          ELEMENT info;
          struct pila *p_next;
          };
          
     struct pila *ptr;
     ptr=calloc(1,sizeof(struct pila));
     memcpy(ptr,dato,len);
     ptr->p_next=(struct pila *)head->p_next;
     (struct pila *)head->p_next=ptr;
}

void elim_nodo(void *head)
{
     struct pila {
          ELEMENT info;
          struct pila *p_next;
          };
          
	 struct pila *eliminato;
	 eliminato=(struct pila *)head->p_next;
     (struct pila *)head->p_next=eliminato->p_next; //l'elemento precedente punta a quello successivo a quello eliminato
     free(eliminato);
} 
Ho seguito passo passo le parole della prof ma non vuole saperne di partire.. Credo di essermi perso con qualche puntatore.. Ma non riesco a capire il perchè..

Grazie per eventuali consigli..

4 Risposte

  • Re: Gestione di una pila tramite lista

    È vietato per qualche motivo percui questo pezzo di codice non debba essere globale?
    
    struct pila {
              ELEMENT info;
              struct pila *p_next;
              };
    
    Ah mi dimenticavo: il prof sadista.
  • Re: Gestione di una pila tramite lista

    Infatti! Io non capisco l'utilità di questo tipo di creazione di lista.. In pratica lei dice che creando delle funzioni che passano puntatori di tipo void ossia di tipo non specificato, e possibili adattare quelle funzioni ad ogni tipo di parametro che gli viene passato..

    In pratica la struct che dichiaro localmente non cambia mai mentre quella globale si..

    Mi sto ammazzando per studiare queste liste.. Questo è lo stesso programma con il nodo sentinella e funziona perfettamente..
    
    #include <stdio.h>
    #include <stdlib.h>
     
    struct pila {
           char c;
           struct pila *p_next;
           };
    
    struct pila *crealista();
    void ins_nodo(char dato, struct pila *head);
    void elim_nodo(struct pila *head);
    
    void main()       
    {
           char dato;
           struct pila *head, *punt;
           short scelta=1, elem=0, sentinella;
           
           head=crealista(); //creo il nodo sentinella
           head=calloc(1,sizeof(struct pila));
           
           while(scelta!=0) //entro nel menu..
           {
               system("cls");
               printf(" ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n");
               printf(" º Programma per la GESTIONE DI UNA PILA TRAMITE LISTA º\n");
               printf(" ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n");
               
               if(elem>0)
               {
                   sentinella=0;
                   printf("\n   Ecco la tua pila:\n\n"); //visualizzo la pila
                   punt=head;
                   printf("\t ÉÍÍÍ»\n");
                   while(punt->p_next!=NULL)
                   {
                       if(sentinella==1) printf("\t º %c º\n",punt->c); 
                       sentinella=1;                 
                       punt=punt->p_next;
                   }
                   printf("\t º %c º\n",punt->c); 
                   printf("\t ÈÍÍͼ\n");
               }
               else printf("\n   La PILA e' attualmente vuota..\n"); //se la pila è vuota..
               
               puts("");
               //menù
               printf(" ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n");
               printf(" º ---> 1 per aggiungere un elemento alla PILA º\n");
               printf(" º ---> 2 per eliminare un elemento dalla PILA º\n");
               printf(" º ---> 0 per uscire dal programma...          º\n");
               printf(" ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n");
               
               printf("\n Scelta: "); fflush(stdin); scanf("%d",&scelta);
               
               if(scelta==1) //se scelgo 1..
               {
                   do{
                       printf("\n Inserisci il carattere da inserire nella PILA: "); fflush(stdin); scanf("%c",&dato);
                       if(dato=='\n') printf(" ---> ERRORE: Il carattere INVIO non e' ammesso nella PILA!\n");
                     }while(dato=='\n'); //se inserico INVIO non mi ripete l'inserimento..
                       
                   ins_nodo(dato,head);
                   printf("\n Elemento inserito!\n\n");
                   elem++;
               }
    
               
               if(scelta==2) //se scelgo 2..
               {
                   if(elem==0) printf("\n La tua pila e' VUOTA!!\n"); //se la pila è gia vuota..
                   else
                   {
                       elim_nodo(head);
                       elem--;
                       printf("\n Elemento eliminato!!\n"); //altrimenti effettuo eliminazione in testa..
                   }
               }                   
                                    
                printf("\n\n"); system("pause");
           }
    }
    
         
    struct pila *crealista()
    {
           struct pila *testa;
           testa=NULL;
           return testa;
    }
    
    void ins_nodo(char dato, struct pila *head)
    {
         struct pila *ptr;
         ptr=calloc(1,sizeof(struct pila));
         ptr->c=dato;
         ptr->p_next=head->p_next;
         head->p_next=ptr;
    }
    
    void elim_nodo(struct pila *head)
    {
    	 struct pila *eliminato;
    	 eliminato=head->p_next;
         head->p_next=eliminato->p_next; //l'elemento precedente punta a quello successivo a quello eliminato
    } 
    
    Questo ha la struct dichiarata globalmente e funziona benissimo (in questo caso il nodo sentinella è utilissimo).. Mah..

    Di questo passo alla fine del corso sarò completamente pazzo xD
  • Re: Gestione di una pila tramite lista

    Ma che senso ha fare il cast per un listato di cui hai tutti i tipi di dati. Posso capire se una funzione ti arriva da esterno e tu hai solo la dichiarazione (e qui sta anche il problema). Tu come programmatore non puoi assumere che un void * possa essere convertito in un qualsiasi tipo di dato senza che mandi in crash il programma. Quindi il metodo spiegato è molto pericoloso e senza basi. Ha senso nel caso di passaggio parametri a differenti thread ma non in questi esempi. cmq questo si compila ma non so se funziona.
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
    	char c;
    } ELEMENT;
    
    void *crealista();
    void ins_nodo(short len, ELEMENT dato, void *head);
    void elim_nodo(void *head);
    
    void main()       
    {
    
    	struct pila {
    		ELEMENT info;
    		struct pila *p_next;
    	};
    	ELEMENT dato;
    	struct pila *head, *punt;
    	short scelta=1, elem=0, sentinella=0, len;
    
    	head=(struct pila *)crealista(); //creo il nodo sentinella
    	head=calloc(1,sizeof(struct pila));
    
    	len=sizeof(ELEMENT);
    
    	while(scelta!=0) //entro nel menu..
    	{
    		system("cls");
    		printf(" ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n");
    		printf(" º Programma per la GESTIONE DI UNA PILA TRAMITE LISTA º\n");
    		printf(" ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n");
    
    		if(elem>0)
    		{
    			printf("\n   Ecco la tua pila:\n\n"); //visualizzo la pila
    			punt=head;
    			printf("\t ÉÍÍÍ»\n");
    			sentinella=0;
    			while(punt->p_next!=NULL)
    			{
    				if(sentinella==1) printf("\t º %c º\n",punt->info.c);
    				sentinella=1;                 
    				punt=punt->p_next;
    			}
    			printf("\t º %c º\n",punt->info.c);
    			printf("\t ÈÍÍͼ\n");
    		}
    		else printf("\n   La PILA e' attualmente vuota..\n"); //se la pila è vuota..
    
    		puts("");
    		//menù
    		printf(" ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n");
    		printf(" º ---> 1 per aggiungere un elemento alla PILA º\n");
    		printf(" º ---> 2 per eliminare un elemento dalla PILA º\n");
    		printf(" º ---> 3 per uscire dal programma...          º\n");
    		printf(" ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n");
    
    		printf("\n Scelta: "); fflush(stdin); scanf("%d",&scelta);
    
    		if(scelta==1) //se scelgo 1..
    		{
    			do{
    				printf("\n Inserisci il carattere da inserire nella PILA: "); fflush(stdin); scanf("%c",&dato.c);
    				if(dato.c=='\n') printf(" ---> ERRORE: Il carattere INVIO non e' ammesso nella PILA!\n");
    			}while(dato.c=='\n'); //se inserico INVIO non mi ripete l'inserimento..
    
    			ins_nodo(len,dato,head);
    			printf("\n Elemento inserito!\n\n");
    			elem++;
    
    		}
    
    		if(scelta==2) //se scelgo 2..
    		{
    			if(elem==0) printf("\n La tua pila e' VUOTA!!\n"); //se la pila è gia vuota..
    			else
    			{
    				elim_nodo(head);
    				elem--;
    				printf("\n Elemento eliminato!!\n"); //altrimenti effettuo eliminazione in testa..
    			}
    		}                   
    
    		printf("\n\n"); system("pause");
    	}
    
    
    }
    
    void *crealista()
    {
    	struct pila {
    		ELEMENT info;
    		struct pila *p_next;
    	};
    
    	struct pila *testa;
    	testa=NULL;
    	return testa;
    }
    
    void ins_nodo(short len, ELEMENT dato, void *head)
    {
    	struct pila {
    		ELEMENT info;
    		struct pila *p_next;
    	};
    
    	struct pila *ptr;
    	ptr= (struct pila *)calloc(1,sizeof(struct pila));
    	ptr->info = dato;
    	(ptr->p_next) = ((struct pila *)head)->p_next;
    	((struct pila *)head)->p_next=ptr;
    }
    
    void elim_nodo(void *head)
    {
    	struct pila {
    		ELEMENT info;
    		struct pila *p_next;
    	};
    
    	struct pila *eliminato;
    	eliminato=((struct pila *)head)->p_next;
    	((struct pila *)head)->p_next=eliminato->p_next; //l'elemento precedente punta a quello successivo a quello eliminato
    	free(eliminato);
    }
    
  • Re: Gestione di una pila tramite lista

    Funziona! Grazie mille!
Devi accedere o registrarti per scrivere nel forum
4 risposte