Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Deklaracje funkcji z wielokropkiem (...) jako ostatni argument przyjmują zmienną liczbę argumentów. Język C++ zapewnia sprawdzanie typów tylko dla jawnie zadeklarowanych argumentów. Można użyć list argumentów zmiennych, gdy liczba i typy argumentów funkcji mogą się różnić.
printf
Rodzina funkcji jest przykładem funkcji, które mają listy argumentów zmiennych.
Funkcje z argumentami zmiennych
Aby uzyskać dostęp do argumentów po tych zadeklarowanych, użyj makr zawartych w standardowym pliku nagłówkowym <stdarg.h>
, jak wyjaśniono w tym artykule.
Specyficzne dla firmy Microsoft
Język Microsoft C++ umożliwia określenie wielokropka jako argumentu, jeśli wielokropek jest ostatnim argumentem, a przecinek pojawia się przed wielokropkiem. W związku z tym deklaracja int Func( int i, ... );
jest legalna, ale int Func( int i ... );
nie jest.
Koniec specyfiki Microsoftu
Deklaracja funkcji, która przyjmuje zmienną liczbę argumentów, wymaga co najmniej jednego argumentu zastępczego, nawet jeśli nie jest używana. Jeśli ten argument zastępczy nie zostanie podany, nie ma możliwości uzyskania dostępu do pozostałych argumentów.
Gdy argumenty typu char
są przekazywane jako argumenty zmiennych, są konwertowane na typ int
. Podobnie, gdy argumenty typu float
są przekazywane jako argumenty zmiennych, są konwertowane na typ double
. Argumenty innych typów podlegają zwykłym promocji całkowitych i zmiennoprzecinkowych. Aby uzyskać więcej informacji, zobacz Konwersje standardowe.
Funkcje wymagające list zmiennych są deklarowane przy użyciu wielokropka (...) na liście argumentów. Użyj typów i makr opisanych w <stdarg.h>
pliku dołączania, aby uzyskać dostęp do argumentów przekazywanych przez listę zmiennych. Aby uzyskać więcej informacji na temat tych makr, zobacz va_arg, va_copy, va_end, va_start.
W poniższym przykładzie pokazano, jak używać makr do przetwarzania listy argumentów zmiennych:
// 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
W poprzednim przykładzie przedstawiono następujące ważne pojęcia:
- Przed uzyskaniem dostępu do argumentów zmiennych należy ustanowić znacznik listy jako zmienną typu
va_list
. W poprzednim przykładzie znacznik nosi nazwęvl
. - Dostęp do poszczególnych argumentów uzyskuje się przy użyciu makra
va_arg
. Należy poinformowaćva_arg
makro o typie argumentu do pobrania, aby można było przenieść prawidłową liczbę bajtów ze stosu. Jeśli określisz nieprawidłowy typ rozmiaru innego niż podany przez program wywołujący dova_arg
programu , wyniki są nieprzewidywalne. - Należy jawnie rzutować wynik uzyskany przy użyciu makra
va_arg
do żądanego typu. - Aby zakończyć przetwarzanie argumentów zmiennych, należy wywołać
va_end
makro.