PDA

Visualizza la versione completa : [C] Chiarimento sull' uso dei puntatori


Darèios89
17-10-2012, 18:26
Copio da una pagina web:



void funzione_stupida( int *x ) {
*x++;
}
...
mail() {
int y = 10;
...
funzione_stupida( &y );
...
}

L'esempio mostra la dichiarazione e descrizione di una funzione che non restituisce alcun valore, e riceve un parametro puntatore a un intero. Il lavoro della funzione è solo quello di incrementare il valore contenuto nell'area di memoria a cui si riferisce tale puntatore.

Poco dopo, nella funzione main() inizia il programma vero e proprio; viene dichiarata la variabile y, un intero normale inizializzato a 10, e a un certo punto viene chiamata la funzione vista prima, passando il puntatore a y.

Il risultato è che dopo la chiamata, la variabile y contiene il valore precedente incrementato di un'unità.

Il mio dubbio è, perchè se il metodo usa puntatori non li uso nel main? Quando passo &y quella locazione contiene 10, ma non punta ad un' altra cella di memoria......accade forse perchè non essendo un puntatore viene modificato il valore medesimo della locazione che passo come parametro?

MItaly
17-10-2012, 18:51
Occhio, non stai passando y, ma &y. L'operatore & ottiene l'indirizzo della variabile su cui viene applicato, "creando" un puntatore che punta ad essa.

Darèios89
17-10-2012, 18:56
Ah...già cambia qualcosa. Quindi se avessi passato come parametro "y" credo che avrei avuto errore di compilazione. In quel modo in sostanza per come è definito il metodo passando &y è come fare: int *pn = &y, cioè viene creato un puntatore che non vedo e quindi il metodo funziona. Giusto?

c0der
17-10-2012, 19:10
Aggiungo che nella funzione_stupida ti sei dimenticato le parentesi,
dovevi scrivere:
(*x)++;
invece di
*x++; // in questo modo se stampassi "y" nella main varrebbe ancora 10

Lascio a te capire la differenza, perché è abbastanza basilare.

MItaly
17-10-2012, 19:10
Originariamente inviato da Darèios89
Ah...già cambia qualcosa. Quindi se avessi passato come parametro "y" credo che avrei avuto errore di compilazione.
Esattamente.

In quel modo in sostanza per come è definito il metodo passando &y è come fare: int *pn = &y, cioè viene creato un puntatore che non vedo e quindi il metodo funziona. Giusto?
Sì; in generale comunque il fatto che "nascano" oggetti temporanei all'interno delle espressioni (senza che siano esplicitamente assegnati a variabili) è una cosa normale, ti ci devi fare l'abitudine. :)

Darèios89
17-10-2012, 19:18
Lascio a te capire la differenza, perché è abbastanza basilare.

Mh....credo che con le parentesi incremento il valore contenuto nella locazione di memoria puntata, nel secondo caso, incremento il valore del puntatore? Cioè della locazione di memoria che punta? Non mi torna chiarissimo...

Facevo questa domanda per un dubbio studiando le socket, ho la chiamata:


int bind(int sockfd, struct sockaddr *my_addr,
int addrlen);

E poi leggo:


nella chiamata, l’argomento ha un tipo specifico struct
sockaddr xxx *, reso legale via type casting; p.es.:

struct sockaddr in thisAddr; // da inizializzare
...
bind(sd, (struct sockaddr * ) &thisAddr, alen);

Ma perchè devo fare cast? Nell' esempio precedente (stupido) non ho fatto alcun cast, non è simile?

oregon
17-10-2012, 19:25
Fai attenzione ... la struttura passata è di tipo

sockaddr_in

mentre la funzione si aspetta il puntatore ad una generica struttura

sockaddr

Ecco perché è necessario il cast.

MItaly
17-10-2012, 19:26
Originariamente inviato da Darèios89
Mh....credo che con le parentesi incremento il valore contenuto nella locazione di memoria puntata, nel secondo caso, incremento il valore del puntatore? Cioè della locazione di memoria che punta?
Sì.

Non mi torna chiarissimo...
Se stesse puntando ad un elemento di un array, incrementare il puntatore lo farebbe puntare all'elemento successivo.

Originariamente inviato da oregon
Fai attenzione ... la struttura passata è di tipo

sockaddr_in

mentre la funzione si aspetta il puntatore ad una generica struttura

sockaddr

Ecco perché è necessario il cast.
Aggiungo: in questo caso è lecito (perché la sockaddr è di fatto l'"inizio" della sockaddr_in), ma un cast da un tipo di puntatore ad un altro incompatibile dà in generale risultati senza senso.

Però se ancora stai imparando i puntatori lascerei momentaneamente da parte socket & co. (e in generale funzioni che usano "trucchi strani" con i puntatori).

Darèios89
18-10-2012, 10:08
Aaaah ok grazie mille!!!

Loading