PDA

Visualizza la versione completa : [C] Passaggio dei parametri per riferimento


Downloader
04-03-2008, 17:15
Il C lavora solo e soltanto con i passaggi dei valori da una funzione ad un'altra tramite valore.
Ciò nonstante esiste qualche trucchetto che mi consente di fare in modo che un valore che passo come parametro ad una funzione venga poi effettivamente modificato anche all'interno dell'ambiente (ovvero della funzione) chiamante.

Se opero con tipi di dati predefiniti non c'è problema, ma se ad esempio dovessi lavorare con puntatori a liste??

Ad esempio:

dichiaro una struttura del tipo


struct lista {
int d;
struct lista *next;
};


e tramite la funzione creaLista popolo la lista e restituisco un puntatore


struct lista *creaLista(int val)
{
if (val < 1)
return NULL;
else {
struct lista *l = (struct lista *) malloc(sizeof(struct lista));
l->d = val--;
l->next = creaLista(val);
return l;
}

}


adesso voglio crearmi una funzione che chiamerò cambiaElemento la quale prenderà come input un intero che rappresenta il numero di spostamenti che voglio effettuare e il puntatore alla lista.
La funzione avrà ritorno void, ma io dovrò modificare l'indirizzo a cui punta il puntatore alla lista (che chiamo l e che è dichiarato nel main) in modo tale che la nuova testa della lista non sarà più il primo effettivo elemento della lista, ma sarà determinata dal numero di spostamenti che dovrò fare (indicati da val) a partire dal primo elemento della lista.

esempio:
se da 1->3->5->4->3->NULL
dico che val = 2 allora il primo elemento della lista diventerà 5 e la lista sarà cosi:
5->4->3->NULL




void cambiaElemento(int, struct lista *);


Tutto ciò per non usare i return e per imparare come si fa un passaggio di parametri per riferimento.

Ma come faccio??
Mi date una mano?

Grazie

oregon
04-03-2008, 18:18
Originariamente inviato da Downloader
Il C lavora solo e soltanto con i passaggi dei valori da una funzione ad un'altra tramite valore.

Chi te lo ha detto?



Ciò nonstante esiste qualche trucchetto che mi consente di fare in modo che un valore che passo come parametro ad una funzione venga poi effettivamente modificato anche all'interno dell'ambiente (ovvero della funzione) chiamante.

Trucchetto? Lo fai NORMALMENTE con i puntatori ...

Non capisco queste premesse ...

Downloader
04-03-2008, 18:23
Mah, io ho sempre saputo cosi a dire il vero.

Comunque sia, potresti darmi una mano??

oregon
05-03-2008, 00:27
Stai parlando di C ... quindi vuoi passare i dati con un puntatore?

Se vuoi passare un intero per puntatore scrivi

void funzione(int *a)

e nella funzione puoi modificare il valore della variabile che hai passato per puntatore ...

O volevi sapere altro?

Downloader
05-03-2008, 07:31
Volevo sapere questo:

Se si lavora con un intero non ho problemi a fare un puntatore, ma se dovessi lavorare con una struttura (come nell'esempio di sopra come posso fare??).

Ad esempio:
riferiamoci al codice che ho precedentemente scritto e assumiamo che dal main io mi sia dichiarato una variabile puntatore ad una struttura chiamato struct lista *l.
Tramite una funzione ricorsiva popolo la lista e adesso voglio fare un passaggio di parametri per riferimento ad una una certa funzione F(x) (tipo di ritorno void).

Ma come faccio??
se ad esempio nel main lancio la funzione in questo modo:
F(&l) passo effettivamente l'indirizzo di memoria del puntatore alla testa della lista l, ma ricevo un warning.

nella funzione che voglio lanciare cosa devo specificare come tipo del parametro?
sempre struct lista *??
Ovvero ad esempio come prototipo dovrei scrivere

void F (struct lista *);??

oregon
05-03-2008, 07:52
Se nel main scrivi



int main(void)
{
struct lista *l;

...
}


e la tua funzione e'

void F (struct lista *);

allora devi passare semplicemente

F(l);

perche' l e' gia' un puntatore alla struttura ...

Se scrivi

F(&l);

passi un puntatore ad un puntatore alla struttura e ottieni giustamente il warning ...

Downloader
05-03-2008, 14:35
Quindi mi stai dicendo che se faccio cosi:



int main()
{
int n = 10;M
struct lista *l = creaLista(n);
F(l,2);
}


e nella funzione scrivo:


void F (struct lista *l, int n)
{
while (n-- > 0)
l = l->next;
}


eseguo il passaggio del parametro "l" per riferimento??

oregon
05-03-2008, 15:14
Un attimo ... rischiamo di fare confusione ...

Essendo il dato "un puntatore" cosi' lo passi sempre per valore ... se lo vuoi passare per riferimento, allora devi usare l'operatore &

Ma tu volevi sapere come poterti spostare all'interno della lista una volta passato il puntatore alla funzione ... e quindi basta il valore del puntatore e il codice che hai scritto va bene (a patto che fai anche i controlli di validita' del valore del puntatore ...)

Downloader
05-03-2008, 18:52
Originariamente inviato da oregon
Un attimo ... rischiamo di fare confusione ...

Essendo il dato "un puntatore" cosi' lo passi sempre per valore ... se lo vuoi passare per riferimento, allora devi usare l'operatore &

Ma tu volevi sapere come poterti spostare all'interno della lista una volta passato il puntatore alla funzione ... e quindi basta il valore del puntatore e il codice che hai scritto va bene (a patto che fai anche i controlli di validita' del valore del puntatore ...)

No no, io volevo sapere come fare il passaggio per riferimento, usando quindi l'operatore &.
E' per questo che qualche post fa avevo scritto la seguente chiamata a funzione:


F(&l);

MisterBean
05-03-2008, 19:20
Potresti creare un puntatore al puntatore della testa della lista, e lavorare su quello.
Però sono seminuovo di programmazione, quindi...

Loading