Pubblicita'
Funzioni con numero variabile di argomenti C/C++
-

In questo articolo tratteremo il concetto di numero variabile di argomenti da passare ad una funzione.
Ogni funzione solitamente ha un numero fisso di argomenti, in C e C++, come in altri linguaggi, è possibile definire funzioni con un numero variabile di argomenti.Quando viene richiamata una funzione, tutti i suoi argomenti vengono inseriti nello stack (area di memoria). In una funzione a numero variabile di argomenti bisogna prelevare dallo stack tutti i parametri della funzione, conoscendo a priori il numero di argomenti passati.
Per accedere agli argomenti ci sono due strade: utilizzando i puntatori o macro di libreria standard. Entrambe sono semplici ed è libera decisione del programmatore scegliere la via più adatta.
L’utilizzo dei puntatori è deciso dal fatto che, tutti i parametri nello stack, sono in porzioni di memoria contigue, quindi conoscendo il primo parametro possiamo accedere a tutti gli altri attraverso il suo puntatore.int Somma(int numPar, ...) {
int num, somma = 0;
char *par = (char*)&numPar + sizeof(numPar);/* Punto 1 */
for(num = numPar; num > 0; num--) {
somma += *(int*)par;/* Punto 2 */
par += sizeof(int);/* Punto 3 */
}
return somma;
}
In questo esempio è spiegato come ricavare gli argomenti attraverso i puntatori.
Nel Punto 1 viene assegnato il puntatore al primo elemento, da notare che, tutti gli argomenti sono memorizzati in aree di memoria contigue, si prende il puntatore al primo argomento (numero di elementi, in questo caso) e si somma la sua grandezza in byte, in modo da passare alla cella di memoria successiva.
Nel Punto 2 viene sommato il parametro corrente.
Nel Punto 3 viene incrementato il puntatore del numero di byte necessario a passare alla cella di memoria successiva.int Somma(int numPar, ...) {
int num, somma = 0;
va_list par;
va_start(par, numPar);/* Punto 4 */
for(num = numPar; num > 0; num--) {
somma += va_arg(par, int);/* Punto 5 */
}
va_end(par);
return somma;
}
In questo esempio, vengono utilizzate le macro definite nella libreria standard stdarg.h: va_start, va_arg e va_end.
Per reperire gli argomenti utilizziamo una variabile di tipo va_list e la inizializziamo attravero la macro va_start, come nel Punto 4.
Nel Punto 5 viene utilizzata la macro va_arg per ricavare il parametro corrente, definendo anche il tipo di dato che deve essere restituito (int in questo caso).
Alla fine viene richamata la macro va_end per concludere l’accesso ai parametri passati.In altri casi, si può decidere di non passare il numero di argomenti ma una sequenza di argomenti con uno specifico terminatore:
int Somma(int par1, ...)
{
int somma = 0;
char *par = (char*)&par1;
while(*(int*)par != NULL)
{
somma += *(int*)par;
par += sizeof(int);
}
return somma;
}
Nell’esempio è mostrato come la costante NULL è utilizzata come terminatore. L’importante è passare sempre il primo parametro, qualsiasi sia il suo senso, perchè è da quel parametro che ci possiamo ricavare tutti gli altri.
Fra i due metodi, personalmente, preferisco quello con i puntatori: ad occhio poco leggibile (cast e vari operatori) ma più maneggevole (scorrere avanti e indietro i parametri) e si evita di utilizzare macro.
Vuoi tutti gli aggiornamenti di IbA's Blog in tempo reale? Abbonati ai nostri Feed RSS.



Loading...
















Commenti recenti