va_arg ()-va_copy ()-va_end ()-va_start ()- 處理變數引數清單

格式

#include <stdarg.h>
var_type va_arg(va_list arg_ptr, var_type);
void va_copy(va_list dest, va_list src);
void va_end(va_list arg_ptr);
void va_start(va_list arg_ptr, variable_name);

語言層次

ANSI

安全執行緒

說明

當函數採用固定數目的必要引數及可變數目的選用引數時, va_arg()va_copy()va_end()va_start() 函數會存取該函數的引數。 您將必要的引數宣告為函數的一般參數,並透過參數名稱來存取引數。

va_start() 會起始設定 arg_ptr 指標,用於後續呼叫 va_arg()va_copy()va_end()

引數 variable_name 是參數清單中最右邊具名參數的 ID (之前, ...)。 在 va_arg()之前使用 va_start() 。 對應的 va_start()va_end() 巨集必須位於相同的函數中。

va_copy() 會將 dest 起始設定為 src 的副本,如同 va_start() 已套用至 dest ,後接先前用來達到 src之現行狀態的 va_arg() 使用順序一樣。 對於相同的 dest,不得呼叫 va_copy()va_start() 來重新起始設定 dest ,而不介入對 va_end() 的呼叫。

va_arg() 函數會從 arg_ptr給定的位置擷取給定 var_type 的值,並增加 arg_ptr 以指向清單中的下一個引數。 va_arg() 函數可以在函數內任意次數從清單中擷取引數。 var_type 引數必須是 int、long、decimal、double、struct、union 或 pointer 之一,或這些類型之一的 typedef。

需要 va_end() 函數來指出參數掃描結束。 va_start()va_copy() 的每一個呼叫都必須由相同函數中 va_end() 的對應呼叫來比對。

因為被呼叫的函數不一定可以判斷有多少引數,所以呼叫函數應該將引數數目傳達給被呼叫的函數。 若要判斷引數數目,函數可以使用空值指標來發出清單結尾的信號,或將選用引數的計數傳遞為其中一個必要引數。 例如, printf() 函數可以透過 format-string 引數來辨別有多少引數。

回覆值

va_arg() 函數會傳回現行引數。 va_copy()va_end()va_start() 函數不會傳回值。

範例

此範例會將引數的變數數目傳遞至一個函數,該函數會列印每一個引數兩次。
#include <stdio.h>
#include <stdarg.h>
 
int vout(int max, ...);
 
int main(void)
{
   vout(2, "Sat", "Sun");
   printf("\n");
   vout(3, "Mon", "Tues", "Wed");
}
 
int vout(int max, ...)
{
   va_list arg_ptr;
   va_list args_copy;
   int args;
   char *day;
   va_start(arg_ptr, max);
   va_copy(args_copy, arg_ptr);
   args = 0;
   while(args < max)
   {
      day = va_arg(arg_ptr, char *);
      printf("Day: %s\n", day);
      args++;
   }
   va_end(arg_ptr);

   args = 0;
   while(args < max)
   {
      day = va_arg(args_copy, char *);
      printf("Day: %s\n", day);
      args++;
   }
   va_end(args_copy);
}
 
/******************  Output should be similar to:  ****************
Day: Sat
Day: Sun
Day: Sat
Day: Sun

Day: Mon
Day: Tues
Day: Wed
Day: Mon
Day: Tues
Day: Wed
*/

相關資訊