Guarda in realtà sono molto semplici. Non farti spaventare dalle parole del libro...
Iniziamo con il passaggio per valore e riferimento.
Ogni variabile ha un indirizzo di memoria, visto che da qualche parte deve pur risiedere il valore. Quando tu chiami una funzione e come argomento passi una variabile, questa viene passata per valore. Questo significa che di fatto viene fatta una copia del tuo valore, ovvero del numero che contiene la variabile. Questo numero viene memorizzato nel parametro della tua funzione. Quindi:
codice:
void funzione(int n) {
n += 10;
}
int main() {
int numero = 100;
funzione(numero);
return 0;
}
viene copiato il valore di numero, quindi 100, e viene memorizzato in n. Questo che implica? Implica che la nostra funzione opera una modifica (somma il numero 10 ad n) alla variabile n. Ma come abbiamo detto ogni variabile ha un indirizzo di memoria. Quindi la situazione finale è:
codice:
numero = 100;
n = 110;
Detto usando altre parole: la funzione modifica la variabile n, ma la modifica non avviene anche alla variabile numero, in quanto hanno indirizzi di memoria diversi.
Il passaggio per riferimento invece significa passare il riferimento, ovvero l'indirizzo della variabile. Con gli array questo accade automaticamente, nel senso che sono appunto sempre passati per riferimento. Questo che significa, rispetto a quanto detto per il passaggio per valore? Significa che se noi passiamo per riferimento, la variabile numero, all'interno della funzione qualsiasi modifica viene fatta ad n, si riflette su numero. Questo perchè condividono lo stesso spazio in memoria!
Immagina le variabili come due scatole: nel primo caso ho la variabile numero con l'indirizzo (ne sparo uno, solo come esempio) 0xAAAAAA e quando la passo per valore copio il numero che contiene questo indirizzo, ovvero 100.
Nel secondo caso, non passo il numero 100, ma l'indirizzo 0xAAAAAA e di conseguenza n ora ha indirizzo 0xAAAAAA; ergo, non possono che puntare alla stessa cella della memoria.
Ma come si passa per riferimento una variabile? Usando i puntatori e l'operatore &. In pratica un puntatore contiene un indirizzo di memoria che può far riferimento ad un numero o un carattere (ma anche puntare ad una struct, ma le vedrai avanti; e ti chiariranno anche la necessità dei puntatori).
Quindi:
codice:
int numero = 100;
int *n = №
ora n punta alla stessa locazione di numero, e se la modifico vado a modificare per forza il valore di numero.
codice:
#include<iostream>
using namespace std;
void funzione(int n) {
n+=10;
}
void funzione(int *n) {
*n+=10;
}
int main() {
int numero = 100;
cout << "Valore di numero: "<<numero<<endl;
funzione(numero);
cout << "[passaggio di numero per valore.]\nValore di numero attuale: " << numero<< endl;
funzione(&numero);
cout << "\nValore numero dopo passaggio per riferimento: "<<numero<<endl;
return 0;
}
Output:
codice:
Valore di numero: 100
[passaggio di numero per valore.]
Valore di numero attuale: 100
Valore numero dopo passaggio per riferimento: 110
Come vedi non è complicato.