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