Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le dichiarazioni di funzione che terminano con puntini di sospensione (un'ellissi, ...), accettano un numero variabile di argomenti. C++ fornisce il controllo dei tipi solo per gli argomenti dichiarati in modo esplicito. È possibile usare elenchi di argomenti variabili quando il numero e i tipi di argomenti per la funzione possono variare. La printf
famiglia di funzioni è un esempio di funzioni con elenchi di argomenti variabili.
Funzioni con elenchi di argomenti variabili
Per accedere agli argomenti dopo quelli dichiarati, usare le macro contenute nel file <stdarg.h>
di inclusione standard, come illustrato in questo articolo.
Sezione specifica Microsoft
Microsoft C++ consente di specificare i puntini di sospensione come argomento se i puntini di sospensione sono l'ultimo argomento e una virgola precede i puntini di sospensione. Pertanto, la dichiarazione int Func( int i, ... );
è legale, ma int Func( int i ... );
non lo è.
Fine sezione specifica Microsoft
La dichiarazione di una funzione che accetta un numero variabile di argomenti richiede almeno un argomento segnaposto, anche se non viene usato. Se questo argomento segnaposto non viene fornito, non è possibile accedere agli argomenti rimanenti.
Quando gli argomenti di tipo char
vengono passati come argomenti di variabile, vengono convertiti in tipo int
. Analogamente, quando gli argomenti di tipo float
vengono passati come argomenti di variabile, vengono convertiti in tipo double
. Gli argomenti di altri tipi sono soggetti alle consuete promozioni a virgola mobile e integrali. Per altre informazioni, vedere Conversioni standard.
Le funzioni che richiedono elenchi di variabili vengono dichiarate usando i puntini di sospensione (...) nell'elenco di argomenti. Utilizzare i tipi e le macro descritti nel <stdarg.h>
file di inclusione per accedere agli argomenti passati da un elenco di variabili. Per altre informazioni su queste macro, vedere va_arg, va_copy, va_end va_start.
Nell'esempio seguente viene illustrato come utilizzare le macro per elaborare un elenco di argomenti di variabile:
// variable_argument_lists.cpp
#include <stdio.h>
#include <stdarg.h>
// Declaration, but not definition, of ShowVar.
void ShowVar( char *szTypes, ... );
int main() {
ShowVar( "fcsi", 32.4f, 'a', "Test string", 4 );
}
// ShowVar takes a format string of the form
// "ifcs", where each character specifies the
// type of the argument in that position.
//
// i = int
// f = float
// c = char
// s = string (char *)
//
// Following the format specification is a variable
// list of arguments. Each argument corresponds to
// a format character in the format string to which
// the szTypes parameter points
void ShowVar( char *szTypes, ... ) {
va_list vl;
int i;
// szTypes is the last argument specified; you must access
// all others using the variable-argument macros.
va_start( vl, szTypes );
// Step through the list.
for( i = 0; szTypes[i] != '\0'; ++i ) {
union Printable_t {
int i;
float f;
char c;
char *s;
} Printable;
switch( szTypes[i] ) { // Type to expect
case 'i':
Printable.i = va_arg( vl, int );
printf_s( "%i\n", Printable.i );
break;
case 'f':
Printable.f = va_arg( vl, double );
printf_s( "%f\n", Printable.f );
break;
case 'c':
Printable.c = va_arg( vl, char );
printf_s( "%c\n", Printable.c );
break;
case 's':
Printable.s = va_arg( vl, char * );
printf_s( "%s\n", Printable.s );
break;
default:
break;
}
}
va_end( vl );
}
32.400002
a
Test string
Nell'esempio precedente vengono illustrati questi concetti importanti:
- È necessario stabilire un marcatore di elenco come una variabile di tipo
va_list
prima che venga eseguito l'accesso a qualsiasi argomento di variabile. Nell'esempio precedente il marcatore viene denominatovl
. - Ai singoli argomenti si accede usando la macro
va_arg
. È necessario indicare alla macrova_arg
il tipo di argomento da recuperare in modo che sia possibile trasferire il numero corretto di byte dallo stack. Se si specifica un tipo non corretto di dimensione diversa da quella fornita dal programma chiamante ava_arg
, i risultati sono imprevedibili. - È necessario eseguire esplicitamente il cast del risultato ottenuto al tipo desiderato utilizzando la macro
va_arg
. - È necessario chiamare la macro
va_end
per terminare l'elaborazione dell'argomento variabile.