PDA

Visualizza la versione completa : [c] implementazione lista doppio puntatore, passaggio dei parametri


333luca333
14-03-2013, 17:26
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0

struct list{
int valore;
struct list *next;

};

typedef char boolean;
int menu (void);
void init(struct list **ptrptr);
void ins_testa(struct list **ptrptr,int valore);
boolean can_testa(struct list **ptrptr,int valore);
void ins_coda(struct list **ptrptr);
void ord_ins(struct list **ptrptr,int valore);
boolean cerca (struct list *ptr,int valore,struct list **ptrptr);
void stampa (struct list *ptr);


int main(){

int scelta,valore;

boolean a,b;
struct list *ptr; //nn inizializzato, almeno x ora
struct list **ptrptr;
int *val_ptr;
init(ptrptr???);//o lo debbo passare con il doppio punt?

while(scelta=menu()){
switch(scelta){

case 1:

system("CLS");
printf("INSERIMENTO IN TESTA\n");
printf("Inserisci ora il valore che desideri: ");
scanf("%d",&valore);
ins_testa(???,valore); // non sono sicuro sul passaggio di *ptrptr

break;


case 2:

system("CLS");

printf("CANCELLAZIONE IN TESTA\n");
a=canc_testa(???,val_ptr);
if(a=TRUE)
printf("Elemento cancellato con successo\n\n");
else
printf("Nessun elemento da cancellare, lista vuota!!\n\n");

break;

case 3:

system("CLS");

printf("INSERIMENTO IN CODA\n");
printf("Inserisci ora il valore che desideri: ");
scanf("%d",&valore);

ins_coda(???,valore);

break;

case 4:

system("CLS");

printf("INSERIMENTO IN ORDINE\n");
printf("Inserisci ora il valore che desideri: ");
scanf("%d",&valore);

ins_ord( ???,valore );


break;

case 5:

system("CLS");

printf("RICERCA DI UN ELEMENTO\n");
printf("Inserisci ora il valore che desideri cercare: ");
scanf("%d",&valore);
b=(???,valore,???);

break;

case 6:

system("CLS");

printf("STAMPA LISTA\n");
stampa(???);



break;

case 0:

return 0;


}


}





return 0; // legato al valore di ritorno del main!
}


int menu (void){

int x;

printf("\n\nSELEZIONA LA TUA SCELTA\n\n");
printf("1.Per inserire in testa\n");
printf("2.Per cancellare in testa\n");
printf("3.Per inserire in coda\n");
printf("4.Per inserire in ordine\n");
printf("5.Per cercare un elemento\n");
printf("6.Per stampare la lista\n");
printf("0.Per uscire\n");
printf("\n\n\n");
printf("Digita ora la tua scelta");
scanf("%d",&x);

while(x<0||x>6){
printf("Selezione errata\n");
printf("Digita il numero corretto\n");
scanf("%d",&x);



}

return x;

}


void init(struct list **ptrptr){

*ptrptr=NULL; //HO SEMPLICEMENTE INIZIALIZZATO A NULL PRIMA DI USARE IL PUNTATORE


}

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

struct list *tmp;

tmp=*ptrptr;
*ptrptr=(struct list *)malloc(sizeof(struct list));
(*ptrptr)->valore=valore;
(*ptrptr)->next=tmp; //PERCHE' METTO LA PARENTESI??? PER LA PRIORITA'?DATO CHE C'E' IL DOPPIO PUNTATORE?


}

boolean can_testa(struct list **ptrptr,int *val_ptr){


struct list *tmp;

if(*ptrptr!=NULL){

*val_ptr=(*ptrptr)->valore;
tmp=*ptrptr;
*ptrptr=(*ptrptr)->next;
free(tmp);
return TRUE;


}
else

return FALSE;


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


while(*ptrptr!=NULL)

ptrptr=&((*ptrptr)->next);


ins_testa(ptrptr,valore);


}

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

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

ins_testa(ptrptr,valore);




}



boolean cerca (struct list **ptr,int valore,struct list **ptrptr){

boolean found;

found=FALSE;

while(ptr!=NULL && found=FALSE){

if(ptr->valore==valore){

found=TRUE;
*ptrptr=ptr;

}
else

ptr=ptr->next;
}



return found;

}

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

ins_testa(ptrptr,valore);




}


void stampa (struct list *ptr){

while(ptr!=NULL){
printf("%d",ptr->valore);
ptr=ptr->next;


}




}




Buonasera a tutti, in pratica non riesco a capire come passare il doppio puntatore alla funzione chiamata.

St implementando la lista con il doppio puntatore dato che in tal maniera non ho bisogno di aggiornare il puntatore alla lista. Quindi scegliendo l'implementazione con il doppio puntatore nelle funzioni di inserimento in testa, coda, etc. per modificare il puntatore alla testa della lista ho bisogno di conoscere l'indirizzo del puntatore stesso, ed per questo che uso il doppio puntatore (scusate se sono un po' prolisso!!!Ma ho bisogno di capire!)

Mi spiego meglio, con uno spezzone del codice qua sopra:



#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0

struct list{
int valore;
struct list *next;

};

typedef char boolean;
int menu (void);
void init(struct list **ptrptr);
void ins_testa(struct list **ptrptr,int valore);
boolean can_testa(struct list **ptrptr,int valore);
void ins_coda(struct list **ptrptr);
void ord_ins(struct list **ptrptr,int valore);
boolean cerca (struct list *ptr,int valore,struct list **ptrptr);
void stampa (struct list *ptr);


int main(){

int scelta,valore;

boolean a,b;
struct list *ptr; //nn inizializzato, almeno x ora
struct list **ptrptr;
int *val_ptr;
init(ptrptr); //o lo debbo passare con il doppio punt?
.
.
.
.
.
.
void init(struct list **ptrptr){

*ptrptr=NULL;

}




Quindi con la dicitura *ptrptr=NULL inizializzo a NULL l'indirizzo del puntatore alla lista, GIUSTO?

Al chiamante INIT(???) come passo il doppio puntatore o meglio cosa ci devo scrivere?ptrptr?Oppure *ptrptr? Oppure **ptrptr? E perch?

Se da teoria il passaggio dei parametri avviene per valore, in C, e per modificare un valore bisogna passare il riferimento, quindi l'indirizzo, allora io dovrei passare *ptrptr? giusto?

Marco1995
14-03-2013, 17:58
Non ho letto il codice ma dovresti passare l'indirizzo del puntaore...quindi un


Funz(&ptr);
dovrebbe bastare.

P.s. Se nella funzione ti aspetti come parametro un puntatore a puntatore...nel main devi dichiarare ptrptr come puntatore,poi nella funzione ci metti la & davanti.

Loading