Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1

    [C]Problema con una linked list

    Ragazzi sono disperato ho un problema con una linked list ma non riesco a capire dov'è l'errore. Il programma non deve fare altro che creare una linked list con i dati riportati in elementi.
    MI da 2 warning
    53 [Warning] assignment from incompatible pointer type
    54 [Warning] assignment from incompatible pointer type.

    Riporto qui il codice magari qualcuno più esperto di me può dirmi dov'è che sbaglio:




    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #define size 11
    struct elemento
    {
    char *name;
    int numero;
    };
    typedef struct elemento el;
    struct el
    {
    el inf;
    el *p_next;
    };
    el elementi[size]={{"Anna",5},{"Mario",8},{"Giuseppe",6},{"Angela", 0},{"Valerio",-1},{"Fabrizio",7},{"Marianna",1},{"Giovanni",2},
    {"Patrizia",10},{"Valentina",4},{"Sara",9}};
    struct el *crea_lista();


    void visualizza_vista(struct el *);
    int main(int argc,char *argv[])
    {
    struct el *head; /*Puntatore alla testa della lista*/
    puts("A");
    head=crea_lista(); //Chiamata alla function per la creazione della lista
    puts("B");
    visualizza_vista(head); // Chiamata alla function per la stampa della lista
    system("PAUSE");

    }
    /*Funzione per la creazione della lista con il relativo inserimento delle informazioni*/
    struct el *crea_lista()
    {
    struct el *p,*paus;
    int i,num;
    char nome[20];
    elementi[0].numero=num;
    strcpy(elementi[0].name,nome);
    p=(struct el *)malloc (sizeof(struct el));
    p->inf.name=nome;
    p->inf.numero=num;
    paus=p;
    for (i=1;i<size; i++)
    {
    (paus->p_next)=(struct el *)malloc (sizeof(struct el));
    paus=paus->p_next;
    elementi[0].numero=num;
    strcpy(elementi[0].name,nome);
    p->inf.name=nome;
    p->inf.numero=num;
    }
    paus->p_next=NULL;
    }

    /*Funzione per la visualizzazione della lista */
    void visualizza_vista(struct el *p)
    {
    printf("punt_lista --->");
    while (p!=NULL)
    {
    // printf ("%s %d",info.name,info.numero);
    printf("--->");
    p->p_next;
    }
    printf ("NULL\n\n\n");

    }

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    L'intestazione della funzione crea_lista() dice che questa deve restituire un tipo di dato che è "puntatore a struct el", ma nella definizione della stessa non c'è nessuna istruzione return...
    every day above ground is a good one

  3. #3

    [c] Problema con linker list

    Si ho aggiunto il return ma il problema non è risolto infatti il programma non funziona lo stesso.
    Il compilatore mi da due warning [Warning] assignment from incompatible pointer type
    su queste due righe di codice:
    (paus->p_next)=(struct el *)malloc (sizeof(struct el));
    paus=paus->p_next;
    ma non capisco perchè alla fine alloco solo lo spazio di memoria per inerirci un'altra informazione.


    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #define size 11
    struct elemento
    {
    char *name;
    int numero;
    };
    typedef struct elemento el;
    struct el
    {
    el inf;
    el *p_next;
    };
    el elementi[size]={{"Anna",5},{"Mario",8},{"Giuseppe",6},{"Angela", 0},{"Valerio",-1},{"Fabrizio",7},{"Marianna",1},{"Giovanni",2},
    {"Patrizia",10},{"Valentina",4},{"Sara",9}};
    struct el *crea_lista();


    void visualizza_vista(struct el *);
    int main(int argc,char *argv[])
    {
    struct el *head; /*Puntatore alla testa della lista*/
    puts("A");
    head=crea_lista(); //Chiamata alla function per la creazione della lista
    puts("B");
    visualizza_vista(head); // Chiamata alla function per la stampa della lista
    system("PAUSE");

    }
    /*Funzione per la creazione della lista con il relativo inserimento delle informazioni*/
    struct el *crea_lista()
    {
    struct el *p,*paus;
    int i,num;
    char nome[20];
    elementi[0].numero=num;
    strcpy(elementi[0].name,nome);
    p=(struct el *)malloc (sizeof(struct el));
    p->inf.name=nome;
    p->inf.numero=num;
    paus=p;
    for (i=1;i<size; i++)
    {
    (paus->p_next)=(struct el *)malloc (sizeof(struct el));
    paus=paus->p_next;
    elementi[i].numero=num;
    strcpy(elementi[i].name,nome);
    p->inf.name=nome;
    p->inf.numero=num;
    }
    paus->p_next=NULL;
    return (p);
    }

    /*Funzione per la visualizzazione della lista */
    void visualizza_vista(struct el *p)
    {
    printf("punt_lista --->");
    while (p!=NULL)
    {
    // printf ("%s %d",info.name,info.numero);
    printf("--->");
    p->p_next;
    }
    printf ("NULL\n\n\n");
    }

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Allora innanzitutto ti consiglio di leggere un po' il regolamento perché il codice va postato utilizzando i tag "code"... non per capriccio ma perché altrimenti come vedi si perde tutta l'indentazione e non si capisce un tubo

    Per quanto riguarda il problema, purtroppo ci sta una frittata di dichiarazioni, typedef e nomi di variabili praticamente uguali... cerco di sviscerare la cosa:

    paus è di tipo "puntatore a struct el", e il campo "next" è di tipo "puntatore a el" e non a "struct el"... laddove el, secondo la typedef che hai scritto, dovrebbe essere "struct elemento". Quindi la malloc che hai scritto

    codice:
    (paus->p_next) = (struct el *) malloc(sizeof(struct el));
    è errata perché per il campo p_next di paus devi allocare spazio per un dato di tipo el (cioè "struct elemento") e non di tipo "struct el", che è un'altra struttura ancora... quella riga va quindi corretta con

    codice:
    (paus->p_next) = (el *) malloc(sizeof(el));
    oppure con

    codice:
    (paus->p_next) = (struct elemento *) malloc(sizeof(struct elemento));
    Errore simile su questa riga:

    codice:
    paus = paus->p_next;
    a paus, che è di tipo "puntatore a struct el", stai assegnando il campo p_next di paus che è di tipo "el" ovvero "puntatore a struct elemento", ma questo non ti saprei suggerire come correggerlo perché non ho idea di cosa intendevi fare... comunque è chiaro quindi che il compilatore ti segnala questi due warning... "errori" non sono perché si tratta pur sempre di indirizzi, ma stai ricorrendo a puntatori di tipo diverso e quindi almeno dei warning ci stanno, e sono warning da non ignorare altrimenti non funziona nulla.

    Il mio consiglio è di dare dei nomi più "distinguibili" alle strutture, stessa cosa per l'alias definito dalla typedef, altrimenti continuerai a confonderti.
    every day above ground is a good one

  5. #5
    Innanzitutto ti ringrazio per il tuo aiuto YUYevon e sopratutto con la tua eccellente spiegazione, nemmeno il mio prof saprebbe farlo capire meglio e per i tuoi ottimi consigli!!!! E volevo scusarmi per come ho scritto il post.

    Volevo chiedere come posso risolvere la riga di codice sotto
    Codice PHP:
    paus paus->p_next
    Praticamente vorrei solo spostare il puntatore per inserire l'elemento successivo nella lista, niente di più, mi sono reso conto che da come ho impostato il problema non ne potrei uscire. Potresti darmi qualche dritta.

    p.s. Ti ringrazio per il tuo aiuto e per la tua pazienza

  6. #6
    Utente di HTML.it L'avatar di Stoicenko
    Registrato dal
    Feb 2004
    Messaggi
    2,254
    p_next deve puntare a struct el e non a el

    nella struttura struct el cambia

    el* p_next

    con

    struct el* p_next

    cmq pure io ti consiglio di modificare PROFONDAMENTE i nomi delle strutture e dei typedef.. così viene il mal di testa.. e sono pure poche righe di codice

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    EDIT: Stoicenko ti ha già detto parte di quello che ti dico in questo post, ho letto solo dopo aver postato...

    Beh guarda ora che rileggo il codice credo che ci sia un errore concettuale di fondo, mentre prima mi sono limitato a correggerti l'errore di compilazione senza badare al contesto... cerco di spiegarmi:

    il nodo della lista è la struttura "struct el". Questa struttura ha come campi il "dato" (che sarebbe a sua volta una struttura "struct elemento" (o "el" stando alla typedef)) e un campo next, che tradizionalmente, quando si parla di liste, è un puntatore al prossimo nodo della lista stessa. A questo punto c'è l'errore concettuale di cui dicevo: il campo next dovrebbe essere un puntatore alla stessta struttura che definisce il nodo (quindi a "struct el") e non a "struct elemento" che è solo il dato della tua struttura... non so se è chiaro... dovresti modificare la tua struct el in questo modo (lasciando inalterato il resto):

    codice:
    struct el {
       el inf;
       struct el *p_next; /* puntatore al prossimo nodo, che è sempre di tipo "struct el"! */
    }
    fatto questo, l'assegnazione paus = paus -> p_next è più che legittima, appunto perché in tal caso i tipi coincidono (a differenza di prima).

    Questo però significa pure che allora la malloc che avevi scritto originariamente (e che io ti ho corretto) andava bene, solo che c'era questo errore nella dichiarazione del campo p_next... quindi sostituisci di nuovo la chiamata a malloc con

    codice:
    (paus->p_next) = (struct el *) malloc(sizeof(struct el));
    che è corretta (prima non lo era appunto perché avevi dichiarato male il campo "p_next" della struttura).

    Ah comunque occhio che c'è un errore anche nella funzione "visualizza_vista()":

    codice:
    void visualizza_vista(struct el *p)
    {
        printf("punt_lista --->");
        while (p != NULL) {
    // printf ("%s %d",info.name,info.numero);
    	printf("--->");
    	p->p_next;
        }
        printf("NULL\n\n\n");
    }
    su quella riga evidenziata il gcc mi dice

    ciao.c:65: warning: statement with no effect

    penso non ci sia bisogno di spiegare perché :]

    Comincia ad apportare queste correzioni, poi se continui ad avere problemi posta il codice corretto con i tag "code" e ci ragioniamo ancora... e resta comunque valido il consiglio di dare nomi alle strutture un po' più distinguibili, facendo però attenzione a non scombinare niente: potresti fare così:

    codice:
    struct dato {
        char *name;
        int numero;
    };
    
    typedef struct dato DATO;
    
    struct nodo {
        DATO inf;
        struct nodo *p_next;
    };
    
    typedef struct nodo NODO;
    E visto che mi trovo scrivendo... un'ultima cosa: nella funzione "crea_lista" cosa intendi fare con quelle strcpy? Per come hai scritto (ad esempio) la prima pare che tu voglia copiare il contenuto di "nome" in elementi[0].name, il che è sbagliato innanzitutto perché in nome non c'è niente, e poi perché il campo name della struttura è solo un puntatore, quindi avresti irrimediabilmente un segmentation fault... forse intendevi fare il contrario, cioè copiare il contenuto di elementi[0].nome in name... in quel caso gli argomenti della strcpy() vanno invertiti:

    codice:
    char * strcpy ( char * destination, const char * source );
    every day above ground is a good one

  8. #8
    Ho accettato il vostro consiglio di modificare i nomi delle strutture e ho modificato l'intero programma, però come sempre c'è qualcosa che non va.
    Infatti quando vado ad assegnare al nodo i valori mi dice che c'è una referenza incompleta. Ma non capisco il perchè eppure l'assegnazione è giusta almeno credo.. Perfavore datemi qualche dritta.....

    Codice PHP:
    #include <stdio.h> 
    #include <stdlib.h> 
    #include<string.h> 
    #define size 11 
    struct dato
     
    char *nameint numero
    }; 
    typedef struct dato DATO
    struct nodo 
    {
     
    DATO infstruct nodo *p_next
    }; 
    typedef struct nodo NODO
    int numeri[size]={5,8,6,0,-1,7,1,2,10,4,9}; 
    char *nomi[size]={"Anna","Mario","Giuseppe","Angela","Valerio","Fabrizio","Marianna","Giovanni","Patrizia","Valentina","Sara"};  

    struct NODO *crea_lista(); //creazione della lista 
    int main(int argc,char *argv[])//main 

    struct  NODO *head/*Puntatore alla testa della lista*/;
     
    head=crea_lista(); //Chiamata alla function per la creazione della lista
    system("PAUSE");  }
     
    /*Funzione per la creazione della lista con il relativo inserimento delle informazioni*/ 
    struct NODO *crea_lista() 

    struct NODO *p,*paus
    int i,num
    char nome[20]; 
    numeri[0]=num
    strcpy(nome,nomi[0]);
    p=(struct NODO *)malloc(sizeof(struct NODO *)); 
    [
    B]p->numero=num
    p->name=nome; }[/B

  9. #9
    Utente di HTML.it L'avatar di Stoicenko
    Registrato dal
    Feb 2004
    Messaggi
    2,254
    ci provo

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #define size 11
    struct dato
    { char *name; int numero;
    };
    typedef struct dato DATO;
    struct nodo
    {
    DATO inf; struct nodo *p_next;
    };
    typedef struct nodo NODO;
    int numeri[size]={5,8,6,0,-1,7,1,2,10,4,9};
    char *nomi[size]={"Anna","Mario","Giuseppe","Angela","Valerio","Fabrizio","Marianna","Giovanni","Patrizia","Valentina","Sara"};  
    
    NODO *crea_lista(); //creazione della lista
    int main(int argc,char *argv[])//main
    {
    NODO *head; /*Puntatore alla testa della lista*/;
    head=crea_lista(); //Chiamata alla function per la creazione della lista
    system("PAUSE");  }
    /*Funzione per la creazione della lista con il relativo inserimento delle informazioni*/
    NODO *crea_lista()
    {
    NODO *p,*paus;
    int i,num;
    char nome[20];
    numeri[0]=num;
    strcpy(nome,nomi[0]);
    p=(NODO *)malloc(sizeof(NODO *));
    p->inf.numero=num; //attenzione!! p è un nodo non un dato
    p->inf.name=nome; }

  10. #10
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Ecco Stoicenko già ha risposto però attenzione che questa riga

    p->inf.name=nome;

    anche scritta così è errata perchè sia nome che il campo name della struct dato sono stringhe, quindi si deve ricorrere alla strcpy() per fare la copia... non è come per la classe string del C++ o per il python, col C siamo a un livello di astrazione un po' più basso :]

    Ovviamente non sto a dirlo a Stoicenko che semplicemente non avrà notato che qulle variabili erano stringhe, ma lo dico a 123fabiomichele che aveva commesso l'errore nel codice originario...

    In ogni caso ci sono un paio di cose che ancora non vanno... innanzitutto, questa assegnazione direi che va invertita:

    numeri[0]=num; -> num = numeri[0]

    (non molto belli anche quei due array globali comunque...)

    e poi anche modificando la copia delle stringhe di cui dicevo prima in questo modo:

    codice:
       strncpy(inf.name, nome, strlen(inf.name));
    otterremmo con ogni probabilità un segmentation fault perché il campo name della struttura inf è un semplice puntatore a char, non ha allocato alcuno spazio né staticamente né dinamicamente...
    every day above ground is a good one

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 © 2024 vBulletin Solutions, Inc. All rights reserved.