Newsgroup: it.comp.lang.c++
Titolo: passaggio parametri

Di recente, per la scuola, ho dovuto studiare il passaggio dei parametri 
alle funzioni, ma la cosa mi ha come al solito confuso le idee che prima 
erano chiare. Mi potete togliere qualche dubbio?
1) Il libro dice che le coppie [tipo][nome] che compongono il prototipo 
della funzione si chiamano "parametri formali", mentre i nomi delle 
variabili o le espressioni che si specificano durante la chiamata sono 
"parametri attuali". Io invece li avevo sempre chiamati rispettivamente 
parametri e argomenti. Quale modo e' piu' corretto?
es:
int funz(tipo nome, tipo nome); //parametri formali
funz(var,var3-var2); //parametri attuali
Poi c'e' una parte che parla del passaggio per valore e per 
riferimento/indirizzo (quel / mi piace poco...). Per quanto riguarda il 
passaggio per valore la spiegazione e' fatta bene, ma la parte 
riferimento/indirizzo e' incomprensibile e mi ha fatto venire dei dubbi:
2) Se io passo un puntatore o direttamente l'indirizzo con l'operatore 
&, questo si considera passaggio per indirizzo o passaggio per valore 
(di un indirizzo)?
Invece il fatto che utilizzando parametri reference il passaggio sia per 
riferimento mi sembra ovvio (lo e' vero???)
3) Il libro utilizza "passaggio per indirizzo" e "passaggio per 
riferimento" come sinonimi. Lo sono veramente?
-- 
Devaraja (Xdevaraja87^gmail^c0mX)
Linux Registerd User #338167
http://counter.li.org

>
Come al solito mi hai chiarito molti dubbi. Grazie.


 dell'oggetto intero sullo stack.
Non è esatto. Non esiste il passaggio di parametri "per indirizzo".
Il passaggio di un puntatore è un passaggio per valore (il valore, come
avevi giustamente notato tu, dell'indirizzo). Non è importante il side
effect che ne consegue.
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

 riferimento/indirizzo (quel / mi piace poco...).
E fa bene a non piacerti perché non esiste il passaggio per indirizzo.
Esistono solo tre tipologie di passaggio dei parametri:
per valore, per riferimento e per copy/restore (che il C++ non ha).
Per capire bene che il passaggio tramite puntatori è un passaggio per
valore, prova a compilare ed eseguire questo:
void f(int* p)
{
    int a = 42;
    p = &a;
    std::cout << p << std::endl;
}
int main()
{
    int a = 84;
    int p = &a;
    std::cout << p << std::endl;
    f(p);
    std::cout << p << std::endl;
}
Come vedrai la modifica a p (che è quello che hai passato alla funzione)
è solo locale alla funzione.


 quello che chiami passaggio per indirizzo,
Io non chiamo nulla passaggio per indirizzo, dato che non esiste :-)
Comunque sicuramente il passaggio per riferimento è poi realizzato dal
compilatore con l'uso di puntatori, ma ciò è nascosto al programmatore.


 riferimento" come sinonimi. Lo sono veramente?
In fin dei conti sono la stessa cosa, ma trattandosi di un libro sul 
C++, farebbe bene a distinguere il passaggio per indirizzo (normalmente 
utilizzato in C) da quello per riferimento (usato in C++ e in altri 
linguaggi, vedi Delphi).

 fa il resize di un array e, magari, lo sposta pure in memoria)
Non confondere: la situazione di cui parli è quella in cui si passa, 
normalmente, un puntatore a puntatore. Puoi modificare il valore del 
puntatore puntato, ma non quello del puntatore puntante.
Cioè, se scrivo:
void *realloc(void **p) {
...
}
All'interno di realloc() posso modificare *p, ma non p.

 
si, ho capito cosa intendevi dire .... in senso stretto hai 
ragione (in effetti avevo citato un caso meno chiaro ma più 
comune nella riallocazione dinamica di array).
Ammetterai però che l'uso dei puntatori tal quali, senza 
indirezioni (ad es. riassegnandoli) è un uso abbastanza raro 
degli stessi, ed è più comune l'uso previo dereferencing degli 
stessi, che in pratica consente di avere una reference 
all'oggetto puntato.
Ciao
Soviet_Mario


 ...
Si, hai ragione, ho scritto una grossa cavolata ! !
Grazie della precisazione (in effetti nel codificare ho sempre 
scritto coem dici tu, ma per leggerezza non avevo considerato la 
doppia indirezione)
ciao
Soviet_Mario


 linguaggi, vedi Delphi).
C'è una lieve sfumatura da aggiungere ed è la possibilità di passare il 
puntatore NULL come puntatore mentre non si può passare un riferimento 
nullo. Talvolta può essere utile.
--- bye

 nullo. Talvolta può essere utile.
Hummm... più che utile questo è un "trick" usato dai programmatori C non 
troppo pulito e consentibile solo e soltanto perché il C prevede, 
appunto, SOLO il passaggio per valore.  In realtà, a rigor di logica, se 
una funzione deve accettare un parametro per riferimento, non è corretto 
che si possa passare NULL.

Andrea Laforgia ha scritto:

E in che modo si potrebbe evitare? A volte una funzione decide il suo 
comportamento proprio valutando se un parametro puntatore e' 
utilizzabile o meno. Dovrei usare un parametro in piu' per mantenere lo 
stesso comportamento? E poi cosa passo alla funzione se un puntatore da 
passare non ce l'ho?


 passare non ce l'ho?
Ti poni il problema sbagliato: se non hai qualcosa da pasare alla 
funzione, allora quella funzione non ti serve.

 posto loro.
Penso sia anche una forma di inveterato istinto ad ottimizzare 
velocità ed occupazione di memoria congenita, che si impara 
presto e diventa automatica.
ciao
Soviet_Mario
  CUT

 automatica.
Questi istinti andrebbero placati, specie in un tempo come quello 
odierno, in cui il compilatore ottimizza sicuramente meglio di come t u 
(programmatore) pensi di poter fare...