Passaggio per riferimento come la parola dice è un riferimento ad una locazione di memoria.
Pensaci un attimo: una variable nominata i sta nella memoria ram in una posizione qualsiasi diciamo nel 1000 byte per semplicità. Adesso il tuo programmino non facceva il passaggio per riferimento ma andava a leggere il valore della cella 1000 e lo passava(copiando il contenuto della cella in un altro posto temporaneo) all funzione leggi. La funzione leggi modificava questa posizione temporanea e all'uscita della funzione questa posizione viene marcata come non usata e la poszione 1000 non veniva affatto modificata. con il passaggio per riferimento tu dici al programma di non andare a leggere cosa c'è nella posizione 1000 ma ti passare la poszione 1000 alla funzione leggi. Sarà poi questa a modificare il contenuto. Questa ha due vantaggi:
1. Non c'è una copia temporanea
2. in variabili molto grosse tipo struct enorme questo (la non copia) ha un impatto considerevole sulla velocità.
Svantaggio: perdi temporaneamente il controllo della variabile nel senso che non sai se la funzione a cui lo passi saprà gestirlo.
leggi questa pagina e fatti una cultura + approfondita:
http://programmazione.html.it/guide/lezione/1175/chiamata-per-valore-e-per-indirizzo/