共用方式為


具有變數引數清單的函式 (C++)

具有省略號(...)作為最後一個參數的函式宣告會接受可變數量的參數。 C++只提供明確宣告自變數的類型檢查。 當函式的自變數數目和類型可能會有所不同時,您可以使用變數自變數清單。 函 printf 式系列是具有變數自變數清單的函式範例。

具有變數引數的函式

若要在宣告參數之後存取其他參數,請使用標準頭文件 <stdarg.h> 中包含的巨集,如本文所述。

Microsoft 特定的

如果省略號是最後一個自變數,且省略號位於省略號之前,Microsoft C++允許將省略號指定為自變數。 因此,宣告 int Func( int i, ... ); 是合法的,但 int Func( int i ... ); 不是。

END Microsoft 特定的

接受可變數量引數的函式宣告至少需要一個佔位引數,即使它未使用也是如此。 如果未提供此佔位元自變數,就無法存取其餘自變數。

當型別 char 的參數作為變數參數傳遞時,它們會轉換為型別 int。 同樣地,當類型float的參數作為變數參數傳遞時,它們會轉換成類型double。 其他類型的引數受限於一般整數和浮點數提升。 如需詳細資訊,請參閱 標準轉換

需要變數清單的函式是使用引數清單中的省略符號 (...) 宣告。 使用 <stdarg.h> include 檔案中所描述的類型和巨集來存取由可變引數清單所傳遞的引數。 如需這些巨集的詳細資訊,請參閱 va_arg、va_copy、va_end va_start

下列範例示範如何使用巨集來處理變數自變數清單:

// 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

前述範例說明了下列重要概念:

  1. 您必須先建立清單標記做為 va_list 類型的變數,才能存取任何變數引數。 在上述範例中,標記稱為 vl
  2. 個別引數是使用 va_arg 巨集存取。 您必須告知 va_arg 巨集要擷取的引數類型,以便從堆疊傳送正確的位元組數目。 如果您對 va_arg 指定的大小類型不正確,且與呼叫程式所提供的大小不同,則結果將無法預期。
  3. 您應該將使用 va_arg 巨集取得的結果明確轉型為您需要的類型。
  4. 您必須呼叫 va_end 巨集來終止多變數處理。