Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18
  1. #1
    Utente di HTML.it L'avatar di Zeldic
    Registrato dal
    Jan 2010
    Messaggi
    80

    [C++] Non riesco a stampare TUTTI gli elementi della Coda

    Ciao! Chi mi saprebbe dire come mai non riesco a stampare a video tutti gli elementi della coda, ma solo il primo e l'ultimo inserito?? E' da tanto che ci provo..

    codice:
    void coda::stampa() {
      elem* indice;
      
      if(indice == NULL)   
        cout << "La coda e' vuota!\n";
        else {
                cout << "La coda contiene i seguenti elementi : \n\n";
                elem* temp = indice;
                
                do {   
                      cout << "<--- [ " << temp->info << " ] ";
                      temp = temp->next;
                }  while(temp != NULL);
                  cout << "\n\n";
        }
    }
    .. E questa era la mia funzione 'enqueue()' : (La sto postando perché ho il dubbio che sia qui l'errore..)

    codice:
    void coda::enqueue(int dato) {
      elem* indice = lista;
      elem* temp = indice;
      
      indice = temp;
      temp = new elem;
      temp->info = dato;
      
      if(indice == NULL) {       
        indice = temp;
        lista = indice;   
      } else {
                lista = indice;        
                temp->next = lista;         
                lista = temp;
        }
    }

  2. #2
    L'errore è nella funzione enqueue, che non riesco neanche a capire bene cosa faccia; un'implementazione (che aggiunge l'elemento davanti alla lista) potrebbe essere questa:
    codice:
    void coda::enqueue(int dato) {
      elem* nuovo=new elem;
      nuovo->info=dato;
      nuovo->next = lista;
      lista = nuovo;
    }
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Ma anche nella

    stampa

    c'è qualcosa che non va ... In particolare, quando scrivi

    elem* indice;

    if(indice == NULL)
    il puntatore indice non è mai stato inizializzato ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  4. #4
    Utente di HTML.it L'avatar di Zeldic
    Registrato dal
    Jan 2010
    Messaggi
    80
    .. Ragazzi, io VI AMOO!!! (Soprattutto Oregon, che in passato mi aiutò anche in Assembly! ).

  5. #5
    Utente di HTML.it L'avatar di Zeldic
    Registrato dal
    Jan 2010
    Messaggi
    80
    .. Sì, però devo aspettare a gioire, infatti.. E mò, come faccio ad inizializzare il puntatore alla struttura nel main (il compilatore mi indica errore se faccio '= NULL')? Uffa.. :master:

  6. #6
    Posta il codice completo che ci ragioniamo.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it L'avatar di Zeldic
    Registrato dal
    Jan 2010
    Messaggi
    80
    Eccolo :

    codice:
    #include <iostream>                      // Direttive in uso dal compilatore.
    using namespace std;
    
    
    class coda { 
      private :
        struct elem {
          int info;
          elem* next;
        };
        elem* lista;     /* 'lista' è un puntatore ad un oggetto 'elem'. */
        
      public : 
        coda() { lista = NULL; }         /* Costruttore. */
        ~coda() { while(lista != NULL) {dequeue();} }        /* Distruttore. */
        void stampa();          
        void enqueue(int dato);  
        int dequeue();
    };
    
    void coda::enqueue(int dato) {
      elem* indice = lista;
      elem* temp = indice;
      
      for(temp = indice; temp != NULL; temp = temp->next) {  // 'temp' rappresenta l'ultimo elemento della coda.
        indice = temp;
        temp = new elem;
        temp->info = dato;
        temp->next = NULL;  
      }
      
      if(indice != NULL)        
        indice->next = temp;
          else         
            lista = temp;
    } /* End enqueue(). */ 
    
    int coda::dequeue() {
      int dato;
      elem* temp;
      
      if(lista == NULL)   
        cout << "La coda e' vuota!\n";
          else {
                  temp = lista;
                  lista = temp->next;   
                  dato = temp->info;
                  
                  cout << "L'elemento estratto e' il seguente ---> [ " << dato << " ]\n\n";
                  delete temp;      
                       
                  return dato;     
          }
    }
    
    void coda::stampa() {  
      if(lista == NULL) {   
        cout << "La coda e' vuota!\n";
        system("PAUSE");
      }
         else {
                 cout << "La coda contiene i seguenti elementi : \n\n";
                 elem* temp = lista;
                 while(temp != NULL) {  
                   cout << "<--- [ " << temp->info << " ] ";
                   temp = temp->next;
                 }
                    cout << "\n\n";
         }
    } /* End stampa(). */
      
    
    main() {
      // Dichiarazione della variabili : 
      coda c;
      int opzione;
      
      do {
      	    cout << "Scegli una della opzioni seguenti : \n\n"
      	            "1 ---> Per inserire un elemento all'interno dalla coda;\n"
      	            "2 ---> Per eliminare un elemento dalla coda;\n"
      	            "3 ---> Per stampare a video gli elementi della coda;\n"
      	            "0 ---> Per terminare il programma.\n\n"
      	            "Inserisci qui la tua scelta : ";
            cin >> opzione; 
            cout << "\n\n";
            
            switch(opzione) {
    		  case 1 : 
                int num;
                
                cout << "Digita l'elemento da inserire nella coda : ";
                cin >> num;
                cout << "\n"; 
                c.enqueue(num);
    	      break;
    	    
    	      case 2 : 
                c.dequeue();
              break;
    		  
    		  case 3 :  
                c.stampa();	    
              break;
    		  
    		  case 0 :  
    		    cout << "Fine del programma!\n\n";
    		  break;
    		  
    		  default : 
    		    cout << "Scelta sbagliata!\n\n";
    		  break;
    	    }
      } while(opzione != 0);
      
    system("PAUSE");
    return 0;
    } /* End main(). */

  8. #8
    Al di là dell'errore che dici che ti dà (qual è?), enqueue è ancora una volta errata: perché continui ad allocare nuovi elementi nel ciclo? Quello che dovresti fare sarebbe creare il nuovo elemento scorrere fino all'ultimo e agganciarlo in fondo, gestendo il caso speciale della lista vuota. Tra l'altro per arrivare all'ultimo elemento ti conviene scrivere un metodo a parte, in maniera da semplificare la logica degli altri metodi che ne necessitano.
    codice:
    /* nota: lastelem deve essere membro privato della classe */
    elem * coda::lastelem()
    {
        if(lista==NULL)
            return NULL;
        elem * ret;
        for(ret=lista; ret->next!=NULL; ret=ret->next)
           ;
        return ret;
    }
    
    void coda::enqueue(int dato) {
        elem * nuovo = new elem;
        elem->info = dato;
        elem->next = NULL;
        if(lista==NULL)
            lista = nuovo;
        else
            lastelem()->next=nuovo;
    }
    dequeue, poi, è un po' un pasticcio, visto che mischia la logica di gestione della coda con quella di interazione con l'utente. Un design più pulito potrebbe essere restituire un valore "magico" o sollevare un'eccezione quando si tenta di svuotare una lista vuota:
    codice:
    int coda::dequeue() {
        if(lista==NULL)
        {
            /* Possibilità 1: restituisco un valore magico che indica che la lista è vuota */
            return std::numeric_limits<int>::min();
            /* Possibilità 2: sollevo un'eccezione (richiede #include <stdexcept> */
            throw std::runtime_error("La coda è vuota.");
        }
        else
        {
            elem * daRimuovere = lista;
            int ret = lista->info;
            lista=lista->next;
            delete daRimuovere;
            return ret;
        }
    }
    (nota: codice scritto al volo, potrebbe avere qualche errore)
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it L'avatar di Zeldic
    Registrato dal
    Jan 2010
    Messaggi
    80

    Grazie!!!! ^_^

    Ciao, MItaly!! Grazie del tuo preziosissimo aiuto!
    Ho tardato un po' nel rispondere, perché volevo comprendere bene il codice che mi avevi scritto.. Ora non posto qui il mio, ma ti assicuro che i tuoi suggerimenti mi sono serviti a molto per la correzione di alcuni errori logici che avevo fatto nelle funzioni di inserimento ed eliminazione di un dato.. Poi appunto come mi hai detto tu di creare un membro privato della classe 'lastelem', che punta all'ultimo elemento della coda, è stato necessario per il suo corretto funzionamento.. Soltanto un paio di cose non mi sono molto chiare, però, e cioé :

    1) Tu mi dici che deve essere un membro privato della classe, ma poi qui lo utilizzi come se fosse un metodo con lo stesso nome..

    codice:
    elem* coda::lastelem() {
      if(lista == NULL)
      
      return NULL;
      elem* ret;
        
        for(ret = lista; ret->next != NULL; ret = ret->next);
        
        return ret;
    }
    .. Questo non riesco a farlo, nemmeno se cambio nome alla funzione, mi risulta che è un errore. Non riesco a creare un metodo di tipo 'elem' che mi ritorni il valore dell'ultimo elemento. E di conseguenza anche :

    codice:
    else
            lastelem()->next=nuovo;
    nella funzione 'enqueue()' non mi è consentito.. Ho risolto comunque diversamente con la creazione di un semplice puntatore all'ultimo elemento nella parte privata;

    2) Nella funzione 'dequeue()' tu hai utilizzato due comandi che non conosco, che però mi potrebbero essere utili :

    codice:
     if(lista == NULL) {
      /* Possibilità 1: restituisco un valore magico che indica che la lista è vuota */
      return std::numeric_limits<int>::min();
      
      /* Possibilità 2: sollevo un'eccezione (richiede #include <stdexcept> */
      throw std::runtime_error("La coda è vuota.");
    per rendere appunto più pulito il codice.. Ma mi dovrebbero restituire qualche valore? Perché così non succede nulla in esecuzione.. E ' normale che non si veda nulla? Non ho capito cosa sia il 'valore magico'..

    In ogni caso sei invitato ad una panzerottata giù dalle mie parti!!

  10. #10

    Re: Grazie!!!! ^_^

    Originariamente inviato da Zeldic
    1) Tu mi dici che deve essere un membro privato della classe, ma poi qui lo utilizzi come se fosse un metodo con lo stesso nome..
    I membri di una classe sono collettivamente i campi e i metodi; ho detto membro quindi intendendo metodo, come mi sembrava fosse evidente dal codice.
    Ho risolto comunque diversamente con la creazione di un semplice puntatore all'ultimo elemento nella parte privata;
    Questo è uno dei classici compromessi: uso un campo che punta all'ultimo elemento (pro: è veloce accedere all'ultimo elemento, contro: lo devi tenere sempre aggiornato) o un metodo che lo trovi (pro: non c'è nulla da tenere aggiornato; contro: bisogna scorrere tutta la lista per arrivare all'ultimo elemento)? A te la scelta, ma nel caso in cui usi il primo metodo devi essere sicuro che esso sia sempre aggiornato.
    per rendere appunto più pulito il codice.. Ma mi dovrebbero restituire qualche valore?
    La prima possibilità sì, nello specifico, restituisce il più piccolo valore rappresentabile da un int (tipicamente su piattaforme a 32 bit -2147483648) considerato come "numero magico", ossia come un numero che il chiamante non deve interpretare come effettivo valore dell'elemento appena tolto, ma come segnalatore che la lista è vuota. In effetti però sarebbe meglio rendere più esplicito questo comportamento bloccando i tentativi di inserire elementi con quel valore ed esponendo il numero magico agli utilizzatori della classe in maniera più chiara, ad esempio tramite un metodo o un campo const.

    Il secondo metodo usa le eccezioni, che sono il metodo preferito in C++ per segnalare gli errori. Se tuttavia non le hai mai studiate, forse è meglio lasciare stare.
    Perché così non succede nulla in esecuzione.. E ' normale che non si veda nulla?
    Sì, perché nel codice del main tu non stai visualizzando quello che ti restituisce il metodo, che di suo non visualizza nulla sullo schermo. Questo fatto è essenziale per un design pulito: una classe come coda si deve limitare a gestire i dati, e lasciare completamente da parte l'interazione con l'utente, che deve invece essere gestita dal codice chiamante.
    In ogni caso sei invitato ad una panzerottata giù dalle mie parti!!
    Panzerotti...
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.