[C] liste doppiamente puntate

di il
12 risposte

[C] liste doppiamente puntate

Buonasera a tutti!!!!

Sono un nuovo provetto programmatore, se almeno così posso dire..., visto che inizio a programmare da poco o addirittura pochissimo.

Vi espongo brevemente il mio quesito.

Stò implementando una lista allocata in maniera dinamica, con l'utilizzo del doppio puntatore, perchè voglio mettere alla prova i miei studi teorici.
In sostanza la teoria dice: che se passo ad una funzione un puntatore doppio, non è necessario aggiornare il puntatore alla testa lista, come nel caso i cui passi alla funzione un semplice puntatore.

Quindi con il doppio puntatore non ho bisogno del valore di ritorno e dovrei avere un'ottimizzaione del codice.

Vi metto qua sotto il codice che ho provato a far girare su codeblocks:

Premetto che secondo me l'errore è nel parametro che passa alla funzione, anzi sicuramente l'errore è là, ma la mia poca esperienza non mi fà capire esattamente dove sbaglio e soprattutto perchè.

#include<stdio.h>
#include<malloc.h>

struct lista{
int val;
struct ele *next;
};
typedef int boolean; //con ciò definisco un nuovo tipo

void visit (struct lista *);
boolean ricerca (struct list *,int,struct list**);
void ins_testa(struct list **ptrptr,int valore);
void ins_coda(struct list**,int);
void ins_ord(struct list**,int);

void main(){
struct list *ptr_lista,**pptr;  //puntatore alla lista
boolean false,true,ritorno;
int scelta,elemento;
true=1;  //dovrebbe essere opzionale fare questa assegnazione dato che poi potrei gestire io il valore di ritorno
false=0;

ptr_lista=NULL; // puntatore alla testa della lista
pptr=&ptr_lista; // inizializzo il mio doppio puntatore



printf("Seleziona opzione desiderata:   \n");
printf("1.Inserimento in testa alla lista\n");
printf("2.Inserimento in coda alla lista\n");
printf("3.Inserimento in ordine nella lista\n");
printf("4.Cancellazione elemento di testa della lista\n");
printf("5.Ricerca di un elemento nella lista\n");
printf("6.Stampa dell'intera lista\n");
printf("0.Per finire\n");
do{
printf("effettua la tua scelta:");
scanf("%d",&scelta);

switch(scelta){

case 1:
    printf("INSERIMENTO IN TESTA ALLA LISTA\n\n");

    printf("Inserisci valore:  ");
    scanf("%d",&elemento);
    ins_testa(pptr,elemento);

    break;


case 2:
    printf("INSERIMENTO IN CODA ALLA LISTA\n\n");
    printf("Inserisci valore: ");
    scanf("%d",&elemento);
    ins_coda(pptr,elemento);
    break;

case 3:
    printf("INSERIMENTO ORDINATO\n\n");
    printf("Inserisci valore:  ");
    scanf("%d",&elemento);
    ins_ord(pptr,elemento);
    break;

case 4:
    printf("CANCELLAZIONE ELEMENTO TESTA DELLA LISTA\n\n\n");
   // qua ancora non ho definito la funzione, spero di arrivarci presto!

case 5:
    printf("RICERCA ELEMENTO ALL'INTERNO DELLA LISTA \n\n");
    printf("Inserisci elemento da ricercare:  ");
    scanf("%d",&elemento);
    ritorno=ricerca(ptr_lista,elemento,pptr);
    if(ritorno==true)
        printf("Elemento trovato!");
    else
        printf("Elemento non presente");

    break;

case 6:
    printf("STAMPA DELLA LISTA\n\n");
    visit(ptr_lista);
    break;


case 0:
    printf("Uscita dal ciclo!");
    break;



}while(scelta!=0);


}


void ins_testa(struct list **ptrptr,int valore){

    struct list *tmp;
    tmp=*ptrptr;
    *ptrptr=(struct list*)malloc(sizeof(struct list));
    (*ptrptr)->val=valore;
    (*ptrptr)->next=tmp;


}

void ins_coda(struct list**ptrptr,int valore){

    while(*ptrptr!=NULL)
        ptrptr=&((*ptrptr)->next);

    ins_testa(ptrptr,valore);



}
void ins_ord(struct list**ptrptr,int valore){

    while(*ptrptr!=NULL && (*ptrptr)->val<valore)
        ptrptr=&((*ptrptr)->next);

    ins_testa(ptrptr,valore);




}

boolean ricerca (struct list *ptr,int valore,struct list**ptrptr){
boolean found;
found=false;
while(ptr!=NULL&&found==false)
{
    if(ptr->val==valore)
    {
        found=true;
        *ptrptr=ptr;
    }
    else
        ptr=ptr->next;
}


}

void visit (struct lista *ptr){
while(ptr!=NULL){
    printf("%d",ptr->val);
    ptr=ptr->next;

}

}







12 Risposte

  • Re: [C] liste doppiamente puntate

    Scorpio_333 ha scritto:


    ... nuovo provetto ...
    Un perfetto ossimoro ...
    Premetto che secondo me l'errore è nel parametro che passa alla funzione
    Quale funzione? Che errore?
  • Re: [C] liste doppiamente puntate

    Ma se
    struct lista{   <--lista
    int val;
    struct ele *next;
    };
    perchè
    boolean ricerca (struct list *,int,struct list**);  <-- list
    ?

    list e' questo

    forse e' questa svista
  • Re: [C] liste doppiamente puntate

    Direi che ale99 ha perfettamente ragione, Grazie.

    E' un errore di svista... almeno per ciò, ma fintanto che non gira non voglio ancor cantar vittoria.
  • Re: [C] liste doppiamente puntate

    oregon ha scritto:


    Scorpio_333 ha scritto:


    ... nuovo provetto ...
    Un perfetto ossimoro ...
    Premetto che secondo me l'errore è nel parametro che passa alla funzione
    Quale funzione? Che errore?


    Allora quale funzione? Praticamente tutte! Dato che per un'omissione di lettera mi si sono generati svariati errori.
  • Re: [C] liste doppiamente puntate

    ale99 ha scritto:


    list e' questo

    forse e' questa svista
    ok, c'è sempre da imparare, e non si finisce mai....
  • Re: [C] liste doppiamente puntate

    Scorpio_333 ha scritto:


    per un'omissione di lettera mi si sono generati svariati errori.
    Non è che gli errori sono in numero proporzionale a quello che dimentichi di scrivere ...
  • Re: [C] liste doppiamente puntate

    Allora usando la giusta NOTAZIONE(struct lista), mi si crea altro problema:

    il quale recita così:

    In function main:
    error: expected declaration or statement at end of imput


    In pratica mi da errore sulla parentesi graffa di chiusura, in questo caso della funzione "visit".
    
    void visit (struct lista *ptr){
    while(ptr!=NULL){
        printf("%d",ptr->val);
        ptr=ptr->next;
    
    }
    
    }
    
    Provo ad isolare il problema eliminando la funzione, ma il problema, lo stesso, si ripropone per la funzione immediatamente sopra:
    
    boolean ricerca (struct list *ptr,int valore,struct list**ptrptr){
    boolean found;
    found=false;
    while(ptr!=NULL&&found==false)
    {
        if(ptr->val==valore)
        {
            found=true;
            *ptrptr=ptr;
        }
        else
            ptr=ptr->next;
    }
    
    
    }
    
    segnalandomi lo stesso problema sulla riga di codice che chiude la funzione, quindi sulla parentesi graffa.

    Ripeto avrei bisogno di capire se il passaggio dei parametri per usare il doppio puntatore è corretto, in modo tale da fissare i miei sforzi su altro, se ciò va bene
    
    .....
    
    struct list *ptr_lista,**pptr;
    ......
    
    ptr_lista=NULL; // puntatore alla testa della lista
    pptr=&ptr_lista; // inizializzo il mio doppio puntatore
    
    // e per il passaggio dei parametri ad esempio per inserimento in testa
    
    .....
    .....
    ....
    switch(scelta){
    
    case 1:
        printf("INSERIMENTO IN TESTA ALLA LISTA\n\n");
    
        printf("Inserisci valore:  ");
        scanf("%d",&elemento);
        ins_testa(pptr,elemento);
    
    .....
    ....
    
    ins_testa(pptr,elemento);
    Vorrei almeno sapere se ciò è corretto? Da nozioni teoriche direi di sì, voi che dite?
  • Re: [C] liste doppiamente puntate

    Prima dei doppi puntatori controlla che non ci siano problemi con le parentesi { } come pare che ci siano. Se mancano parentesi chiuse probabilmente la segnalazione non sarà esattamente dove manca, ecco perché hai difficoltà a trovare il punto giusto.

    Controlla tutto il codice dall'inizio alla fine ...
  • Re: [C] liste doppiamente puntate

    Se usi codeblocks cerca nei plugin la formattazione automatica del sorgente (non mi ricordo il nome esatto ma stá circa a metà). Così identa automaticamente il codice e ti accorgi subito di errori di parentesi
  • Re: [C] liste doppiamente puntate

    Oppure potresti fare
    pptr=malloc ( dimensione di 1 puntatore a struct lista )
    (*pptr)=ptr_lista
    
    modificando il codice di conseguenza

    Vedi tu...
  • Re: [C] liste doppiamente puntate

    Allora il codice è quasi del tutto risolto, funziona l'inserimento in testa, in coda, inserimento ordinato, mi manca ancora da riguardare, la ricerca dell'elemento, e la cancellazione in testa.

    Vi metto il codice risolto, in modo tale che possa essere di aiuto ad altri.

    E VAI!

    P.S. Non ho potuto prima, dato che per motivi di lavoro, non ci ho dedicato altro tempo, sono uno studente lavoratore.
    
    #include<stdio.h>
    #include<malloc.h>
    #define falso 0
    #define vero 1
    struct lista{
    int val;
    struct ele *next;
    };
    typedef int boolean; //con ciò definisco un nuovo tipo
    
    
    //boolean ricerca (struct lista *,int,struct lista**);
    void ins_testa(struct lista **ptrptr,int valore);
    boolean can_testa(struct lista**,int);
    void ins_coda(struct lista**,int);
    void ins_ord(struct lista**,int);
    void init (struct lista **ptrptr);
    void visit (struct lista *);
    
    void main(){
    
    struct lista *ptr_lista,**pptr;  //puntatore alla lista
    //boolean falso,vero,ritorno,found;
    int scelta,elemento;
    ptr_lista=NULL;
    pptr=&ptr_lista;
    //init(&ptr_lista);
    
    
     // verifico se è giusto far così!
    //il puntatore va inizializzato
    
    printf("Seleziona opzione desiderata:   \n");
    printf("1.Inserimento in testa alla lista\n");
    printf("2.Inserimento in coda alla lista\n");
    printf("3.Inserimento in ordine nella lista\n");
    printf("4.Cancellazione elemento di testa della lista\n");
    printf("5.Ricerca di un elemento nella lista\n");
    printf("6.Stampa dell'intera lista\n");
    printf("0.Per finire\n");
    do{
    printf("effettua la tua scelta:");
    scanf("%d",&scelta);
    
    switch(scelta){
    
    case 1:
        printf("INSERIMENTO IN TESTA ALLA LISTA\n\n");
    
        printf("Inserisci valore:  ");
        scanf("%d",&elemento);
        ins_testa(pptr,elemento);
    
    
        break;
    
    
    case 2:
        printf("INSERIMENTO IN CODA ALLA LISTA\n\n");
        printf("Inserisci valore: ");
        scanf("%d",&elemento);
        ins_coda(pptr,elemento);
        break;
    
    case 3:
        printf("INSERIMENTO ORDINATO\n\n");
        printf("Inserisci valore:  ");
        scanf("%d",&elemento);
        ins_ord(pptr,elemento);
        break;
    
    case 4:
        printf("CANCELLAZIONE ELEMENTO TESTA DELLA LISTA\n\n\n");
        /*ritorno=can_testa(pptr,xxxxx);
        if(ritorno==true)
            printf("Elemento eliminato con successo!\n");
        else
            printf("Lista vuota, eliminazione impossibile\n");
    
            */
        break;
    
    case 5:
        printf("RICERCA ELEMENTO ALL'INTERNO DELLA LISTA \n\n");
        printf("Inserisci elemento da ricercare:  ");
        scanf("%d",&elemento);
       /*ritorno=ricerca(ptr_lista,elemento,pptr);
        if(ritorno==vero)
            printf("Elemento trovato!");
        else
            printf("Elemento non presente");
    */
        break;
    
    
    case 6:
        printf("STAMPA DELLA LISTA\n\n");
        visit(ptr_lista);
    
        break;
    
    
    case 0:
        printf("Uscita dal ciclo!");
        break;
    
    
    
    }
    
    
    }while(scelta!=0);
    }
    
    
    void init (struct lista **ptrptr){
    *ptrptr=NULL;
    }
    
    
    void ins_testa(struct lista **ptrptr,int valore){
    
        struct list *tmp;
        tmp=*ptrptr;
        *ptrptr=(struct lista*)malloc(sizeof(struct lista));
        (*ptrptr)->val=valore;
        (*ptrptr)->next=tmp;
    
    
    }
    
    void ins_coda(struct lista**ptrptr,int valore){
    
        while(*ptrptr!=NULL)
            ptrptr=&((*ptrptr)->next);
    
        ins_testa(ptrptr,valore);
    
    
    
    }
    void ins_ord(struct lista**ptrptr,int valore){
    
        while(*ptrptr!=NULL && (*ptrptr)->val<valore)
            ptrptr=&((*ptrptr)->next);
    
        ins_testa(ptrptr,valore);
    
    
    
    
    }
    
    /*boolean can_testa(struct list**ptrptr,int *val_ptr){
    
        struct list *tmp;
    
        if(*ptrptr!=NULL)
        {
            *val_ptr=(*ptrptr)->val;
            tmp=*ptrptr;
            *ptrptr=(*ptrptr)->next;
            free(tmp);
            return true;
        }
        else
            return false;
    
    }
    
    boolean ricerca (struct lista *ptr,int valore,struct lista**ptrptr){
    found=falso;
    while(ptr!=NULL&&found==falso)
    {
        if(ptr->val==valore)
        {
            found=vero;
            *ptrptr=ptr;
        }
        else
            ptr=ptr->next;
    }
    
    
    }
    */
    
    void visit (struct lista *ptr){
    
        printf("Punt_lista--->");
        while(ptr!=NULL){
           printf("%d",ptr->val);
           printf("-->");
           ptr=ptr->next;
    
                    }
        printf("Null\n\n\n");
    }
    
    
    
  • Re: [C] liste doppiamente puntate

    Ptrptr=&((*ptrptr)->next) ciao scusa potresti spiegarmi il significato di questa espressione?e perchè il top continua a puntare all'inizio della lista?perchè ho provato sia ad usare una variabile ausiliaria,sia a non mettere quella & e dopo ptrptr punterà sempre alla fine della lista
Devi accedere o registrarti per scrivere nel forum
12 risposte