Passaggio variabili per indirizzo o per valore
Ciao informatici! sono alle prime armi nella programmazione in C...vi chiedo cortesemente di spiegarmi brevemente la differenza tra il passare le variabili per indirizzo o per valore: come funziona l'uno e l'altro meccanismo e in quali casi è più indicato scegliere l'uno o l'altro modo.
Altra cosa: le matrici, gli array in C vengono passati per indirizzo?
Ultima cosa: i puntatori c'entrano qualcosa con tutto ciò?
Ringrazio chi vorrà rispondermi:)
Altra cosa: le matrici, gli array in C vengono passati per indirizzo?
Ultima cosa: i puntatori c'entrano qualcosa con tutto ciò?
Ringrazio chi vorrà rispondermi:)
Risposte
"aram":
Ciao informatici! sono alle prime armi nella programmazione in C...vi chiedo cortesemente di spiegarmi brevemente la differenza tra il passare le variabili per indirizzo o per valore: come funziona l'uno e l'altro meccanismo e in quali casi è più indicato scegliere l'uno o l'altro modo.
Altra cosa: le matrici, gli array in C vengono passati per indirizzo?
Ultima cosa: i puntatori c'entrano qualcosa con tutto ciò?
Non sono un informatico, ma provero' lo stesso a risponderti.
Il passaggio per valore implica il passare alla funzione il contenuto di un'area di memoria.
Il passaggio per indirizzo implica il passaggio del puntatore all'area di memoria summenzionata.
Usi il secondo sia quando devi passare strutture o array, per es., sia quando vuoi avere la possibilita', dall'interno di quella funzione, di modificare la variabile passata: passando per valore la variabile, l'unica cosa che puoi fare dall'interno della funzione e' cambiare il valore di una copia locale della variabile (tipicamente allocata sullo stack), e quindi non puoi alterare la variabile originaria. Quando passi il puntatore alla variabile, invece, hai la possibilita' di accedere direttamente all'area di memoria originaria.
Quindi direi che si', i puntatori c'entrano eccome

Grazie, mi hai chiarito un po' le idee:)
se invece all'interno della funzione non mi serve modificare il contenuto dell'array, c'è possibilità di passarlo per valore?
se invece all'interno della funzione non mi serve modificare il contenuto dell'array, c'è possibilità di passarlo per valore?
i puntatori invece come funzionano? se ho un puntatore *P, in che senso "punta" a un'area di memoria?? Nel senso che mi restituisce l'indirizzo dell'area di memoria in cui è memorizzata la variabile P?
"aram":
i puntatori invece come funzionano? se ho un puntatore *P, in che senso "punta" a un'area di memoria?? Nel senso che mi restituisce l'indirizzo dell'area di memoria in cui è memorizzata la variabile P?
In soldoni: un puntatore in C e' una variabile che contiene un riferimento a un'area di memoria.
Te lo puoi immaginare come una variabile con dentro l'indirizzo di una locazione di memoria (che e' cio' che tipicamente e'), anche se forse non e' necessario questo avvicinamento "verso il metallo".
Per esempio in
int n=0; int *p=&n;
n e' un intero, e p un puntatore ad intero, inizializzato a puntare alla variabile n (quindi contiene l'indirizzo della locazione di memoria che contiene il valore di n).
Con i puntatori puoi fare diverse operazioni aritmetiche, e ovviamente tanti giochini con allocazione dinamica etc.
I sacri testi contengono tutte le spiegazioni, vedi il K&R.
Per rispondere anche all'altra domanda, il nome di un array (tipo 'a' in 'a[]') e' praticamente un puntatore che punta all'inizio dell'array. Per cui quando vuoi passare un array in realta' passi questo puntatore.
Ok, però mi chiedo: il passare l'indirizzo a cosa mi serve? Mi serve sapere che quella variabile che passo alla funzione è allocata proprio nella i-esima cella di memoria?? Nel senso: all'interno della funzione più che altro mi servirà sapere quanto valeva prima quella variabile, non tanto in quale precisa cella si trova quella variabile...anche se devo modificare il contenuto di quella variabile, mi interesserà, appunto, il contenuto, dell'indirizzo cosa me ne faccio?...scusa ma faccio fatica a capire questo punto-.-
"aram":
Nel senso: all'interno della funzione più che altro mi servirà sapere quanto valeva prima quella variabile, non tanto in quale precisa cella si trova quella variabile...anche se devo modificare il contenuto di quella variabile, mi interesserà, appunto, il contenuto, dell'indirizzo cosa me ne faccio?
Se tu passi alla tua funzione la variabile per valore, quello che succede e' che la funzione accede ad una copia locale della variabile; puoi anche cambiare valore alla copia locale, ma cio' non si riflette in alcun cambiamento del valore della variabile originale. Per cambiare quest'ultima l'unica speranza che hai (parlo del C, non di C++ o C#) e' di conoscere l'indirizzo della variabile.
Ovviamente non stiamo parlando di variabili globali, che sarebbero accessibili dall'interno della funzione.
Per esempio (esempio volutamente stupido):
int fa(int i0) { int i=i0; fb(i); return(i); } void fb(int n) { n+=10; }
qui il valore della variabile i in fa() non viene modificato. Viene modificata solo una inutile variabile nello stack di fb(), che poi viene buttata via.
Invece in:
int fa(int i0) { int i=i0; fb(&i); return(i); } void fb(int *n) { *n+=10; }
la chiamata alla funzione fa(start_val) ritorna il valore di start_val aumentato di 10 (note che la variabile start_val non viene modificata perche' passata per valore). Senza avere il puntatore della variabile passata a fb(), non avresti potuto modificare la variabile i interna a fa().
Spero di essere stato chiaro (e di non aver detto scemenze

Quindi se i è una variabile globale,dire fb(&i) non significa calcolare la funzione fb in i, bensì calcolarla nell'indirizzo della cella contenente i?
"aram":
Quindi se i è una variabile globale,dire fb(&i) non significa calcolare la funzione fb in i, bensì calcolarla nell'indirizzo della cella contenente i?
Beh, si', se vuoi vederla cosi'.
Puo' essere utile tenere questa "rappresentazione inconscia" a basso livello, anche se c'e' da tenere presente che la stessa cosa in linguaggi piu' recenti puo' essere espressa con un po' piu' di astrazione.
Però quel che mi cheido è: in quali rari casi siamo interessati a fare operazioni con l'indirizzo di una variabile? Così, a intuito mi verrebbe da dire che piuttosto l'indirizzo mi serve per poi accedere al contenuto
"aram":
Però quel che mi cheido è: in quali rari casi siamo interessati a fare operazioni con l'indirizzo di una variabile? Così, a intuito mi verrebbe da dire che piuttosto l'indirizzo mi serve per poi accedere al contenuto
Beh, tante volte ti serve la differenza tra due puntatori (cioe' la loro distanza), per esempio hai allocato una area di memoria dinamica, che percorri con dei puntatori in funzione di un qualche algoritmo. Puo' essere parecchio comodo, secondo me.
Inoltre non dimenticare che l'accesso ad un elemento di un array implicitamente usa (anzi, e' equivalente a) la forma *(a+i) con 'i' un intero e 'a' un puntatore.
E' uno di quei problemi per i quali trovi il workaround, ma puo' essere scomodo...