Newsgroup: it.comp.lang.c
Titolo: C'è il trucco?

Ad una domanda di esame viene chiesto:
"Quanti modi esistono in C per passare i parametri ad una funzione? 
Quali sono?"
Io conosco solo quello tradizionale di enumerazione all'interno della 
parentesi tonde come sequenza tipo e nome:
void myfunc(int a, int b);
ad esempio.
Ne esistono anche degli altri?

 Quali sono?"
In molti linguaggi esistono il passaggio per valore e per indirizzo (o 
riferimento).
In C però esiste soltanto quello per valore (perché non è una limitazione?).
Kiuhnm


la domanda mi pare ambigua, io la interpreto in 2 modi:
1. se intende quanti "metodi" esistono: be' potresti mettere 
i parametri in una struttura e passare quella, potresti 
passare i puntatori, ecc...
2. se invece intende quale modo il C usa per passare i 
parametri, allora ne esiste solo uno: per valore. ovvero 
creando una copia del valore da passare sullo stack frame 
della funzione (a meno di non variare la convenzione di 
chiamata, opzione che dipende dal compilatore).
ciao.

 Quali sono?"
Domanda molto ambigua, visto che potrei rispondere: virtualmente infiniti.
Sforzandomi di capire che va cercando l'esaminatore, posso risponderti
dicendo che ne esiste uno solo: il passaggio per valore.
Molti linguaggi (vedi Pascal/C++) prevedono sia il "passaggio per valore"
che il "passaggio per riferimento".  Nel primo caso, si passa alla
funzione un valore e/o una copia del valore di una variabile, ad esempio:
int a=3;
b = somma(4, a); // a somma viene passato un valore e la copia del valore
di a
Nel secondo caso, invece, alla funzione viene passato il riferimento a una
variabile.  Questo fa sě che la funzione possa modificare il valore della
variabile.  Caso tipico in C++:
void somma(int a, int b, int& risultato)
{
  risultato = a+b;
}
...
int a=3, b=4, risultato;
somma(a, b, risultato);
Il passaggio per riferimento non esiste in C, ma esiste solo quello per
valore.  Il ppr viene simulato usando i puntatori, quindi alla funzione
viene passato per valore l'indirizzo di una variabile:
void somma(int a, int b, int* prisultato)
{
  *prisultato = a+b;
}
...
int a=3, b=4, risultato;
somma(a, b, &risultato);
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 
[...]
Aggiungiamo anche le variabili globali?
Sono una porcata, ma c'è anche chi le usa per passare informazioni alla 
funzione.
LP

 Aggiungiamo anche le variabili globali?
No.  Le variabili globali non costituiscono un metodo per passare dati
alle funzioni.


 alle funzioni.
Dipende dall'  esatto significato del termine "passare". In senso 
stretto hai ragione. Nel senso lato di "rendere disponibili i dati all' 
  interno della funzione" (e ovviamente non solo quella)  potrebbe passare.
Giorgio

  interno della funzione" (e ovviamente non solo quella)  potrebbe passare.
No, non è accettabile dal mio punto di vista, perché allora
bisognerebbe contemplare qualsiasi forma di dati disponibili
all'interno della funzione (come i file su disco o una pagina web).
Per "passaggio" si intende appunto ciascuna delle due modalità
normalmente previste nei linguaggi di programmazione.

 normalmente previste nei linguaggi di programmazione.
Ad essere rigorosi, hai pienamente ragione. Comunque permettimi di 
citarti almeno un esempio nel quale il C stesso utilizza una variabile 
globale per passare un dato (o sarebbe meglio dire uno stato) ad una 
funzione. Si tratta della funzione perror che utilizza il valore 
corrente di errno (impostato dalle varie funzioni come fopen et simili, 
per esempio) per generare un messaggio e accodarlo ad un messaggio dato 
dall'utente.
La lettura di info da disco, rete ed altro, non rientrerebbero nel 
passaggio dati in quanto necessitano di funzioni per il loro recupero 
(fgets, per esempio), quindi essendo risultati di altre funzioni, 
necessitano di un nome di file, url, uno stream o quant'altro che deve 
essere "reso disponibile" alla funzione in qualche modo (variabile 
globale, costante, define, o parametro).
Comunque, all'inizio, la mia voleva essere solo una battuta sulla tua 
affermazione
 > Domanda molto ambigua, visto che potrei rispondere: virtualmente 
infiniti.
e io ho solo nominato uno dei tanti modi possibili per mettere una 
funzione a conoscenza di un dato calcolato da un'altra funzione in un 
punto qualsiasi del programma (anche questo rientra nella definizione di 
"passare" anche se non nella definizione di "passare come parametro")
LP

 "passare" anche se non nella definizione di "passare come parametro")
No, questo *non* rientra assolutamente nel concetto di "passare come
parametro".


> interno della funzione" (e ovviamente non solo quella)  potrebbe passare.
Talvolta, nella vita di un programmatore  puo'  essere piu'  importante 
sapere che un dato puo'  essere reso disponibile all'  interno di una 
function mediante variabili globali che attenersi strettamente al 
significato tecnico  di "passaggio". Per cui continuero'  a non togliere 
punti agli studenti che mi parleranno impropriamente di "passaggio 
mediante variabili globali";  anche se io non uso questa terminologia ;-)
Giorgio

mediante variabili globali";
Perché contribuire ad insegnare loro una cosa sbagliata?
Non esiste un "passaggio mediante variabili globali" ed è assurdo che
qualcuno soltanto lo pensi.  Dì pure ai tuoi studenti quello che vuoi,
ci sarà poi chi dovrà correggere quanto da loro appreso ;-)

 vedremo se sarai dello stesso parere.
Taci, imbecille.


Scusate ma se in altri linguaggi, come il Pascal, esiste la differenza 
per valore/per riferimento, in che consiste la differenza?
Cioč per riferimento viene passato alla funzione un puntatore alla 
variabile, ma questo puntatore altro non č che un valore messo nello 
stack e ripescato dalla funzione...
In C questa cosa la deve fare esplicitamente il programmatore, ma č 
sempre un passaggio per valore/per riferimento.
Perchč dire che in C non esiste questa cosa?
-- 
Quando noi ignoranti eravamo di piů, tutto era piů bello...
(A. Celentano)
Per rispondermi in privato, togli prima l'immondizia dalla testa ;)

 Perchè dire che in C non esiste questa cosa?
Perché non esiste. Se non esiste non esiste.
Il programmatore la *emula* tramite l'uso dei puntatori.
Per es. in Pascal ti basta aggiungere "var" e in C++ "&" senza 
modificare il corpo della funzione, ma in C la devi per forza correggere.
Kiuhnm

 Perchè dire che in C non esiste questa cosa?
perché quello che hai descritto non è un passaggio by 
reference, ma sempre by value.
ciao.

Se come modi si intende lo stile allora ne esiste almeno un'altro:
void myfunc(a, b)
int a;
int b;
{
}
E' solo un modo diverso di scrivere la stessa cosa.
Ciao.


C'e' un secondo modo se si intende il modo di scrivere il passaggio... 
ti permette di dichiarare il tipo del parametro che passi all'interno 
della funzione. (sistema obsoleto e anche poco efficace con qualche 
compilatore)
ciaoz.
es:
void funExplain(intVal, strVal)
int intVal;
char *strVal;
{
.........
 
}
On 26 nov 2005, you wrote in it.comp.lang.c:


Se come modi si intende lo stile allora ne esiste almeno un'altro:
void myfunc(a, b)
int a;
int b;
{
}
E' solo un modo diverso di scrivere la stessa cosa.
Ciao.



Credo che la risposta sia qui.
In genere si può passare per valore, per cui all'uscita di una funzione 
il valore passato non viene modificato, ma si può anche passare per 
riferimento mediante puntatore per cui il valore iniziale si cambia 
anche all'uscita di una funzione.
Sillaba

 }
Questo mi ricorda molto la sintassi C89-like empiricamente usata come 
modus operandis nei sorgenti di OpenBSD.
Come giustamente dici, e' solo un modo di scrivere la stessa cosa in 
modi diversi... va capito qual'e' il modo piu' simpatico... e questo e' 
decisamente un gusto personale, sebbene, ricordo, per quanto riguarda 
l'ottica "De raadtiana" C89 e' il must... poi ognuno scrive come gli pare :P
Ciao !