stdarg.h

stdarg.h是C語言中C標準函式館的頭檔案,stdarg是由standard(標準) arguments(參數)簡化而來,主要目的為讓函式能夠接收可變參數。C++的cstdarg頭檔案中也提供這樣的功能;雖然與C的頭檔案是兼容的,但是也有衝突存在。

可變參數函式(Variadic functions)是stdarg.h內容典型的套用,雖然也可以使用在其他由可變參數函式調用的函式(例如,vprintf)。

基本介紹

  • 中文名:stdarg.h
  • 類型:頭檔案
  • 相關學科:C語言
  • 屬於:C標準函式館
可變參數函式,成員,訪問參數,類型安全性,舉例,頭檔案,

可變參數函式

聲明可變參數函式
可變參數函式的參數數量是可變動的,它使用省略號來忽略之後的參數。例如printf函式一般。代表性的聲明為:
int check(int a, double b, ...);
可變參數函式最少要有一個命名的參數,所以
char *wrong(...);
在C中是不被允許的(在C++中,這樣的聲明是合理的)。C中,省略符號之前必須要有逗號;而在C++中,則沒有這種強制要求。
定義可變參數函式
使用相同的語法來定義:
long func(char, double, int, ...);
long func(char a, double b, int c, ...)
{
/* ... */
}
在C的舊形式中可能會出現較省略的函式定義:
long func();
char a;
double b;
long func(a, b, c, ...)
{
/* ... */
}

成員

stdarg.h數據類型
類型名稱
描述
相容
va_list
用來保存宏va_arg與宏va_end所需信息
C89
stdarg.h宏
巨集名稱
描述
相容
va_start
使va_list指向起始的參數
C89
va_arg
檢索參數
C89
va_end
釋放va_list
C89
va_copy
拷貝va_list的內容
C99

訪問參數

訪問未命名的參數,首先必須在可變參數函式中聲明va_list類型的變數。調用va_start並傳入兩個參數:第一個參數為va_list類型的變數,第二個為省略號前最後一個有名字的參數的名稱,接著每一調用va_arg就會返回下一個參數,va_arg的第一個參數為va_list,第二個參數為返回的類型。最後va_end必須在函式返回前被va_list調用(va_list當作參數)(沒有要求要讀取完所有參數)。
C99提供額外的宏,va_copy,它能夠複製va_list。而va_copy(va2, va1)函式作用為拷貝va1到va2。
沒有機制定義該怎么判別傳遞到函式的參數量或者數據類型。函式通常需要知道或確定它們變化的方法。共通的慣例包含:
使用printf或scanf類的格式化字串來嵌入明確指定的類型。
在可變參數最後的標記值(sentinel value)。
總數變數來指明可變參數的數量。

類型安全性

有些C實現提供了對可變參數的擴展,允許編譯器檢查適當的格式化字串及標誌(sentinels)的使用。如果沒有這個擴充,編譯器通常無從檢查傳入函式的未命名參數是否為所預期的類型。因此,必須小心謹慎以確保正確性,因為不匹配的數據類型將導致未定義行為(Undefined behavior)。例如,如果傳遞空指針,不能僅僅寫入NULL(可能實際定義為0),還要轉化為適當的指針類型。另一個考慮是未命名參數的默認的類型提升。float將會自動的被轉換成double。同樣的,比int(整數)更小容量的參數數據類型將會被轉換成int或者unsigned int。函式所接收到的未命名參數必須提前考慮將會出現的數據類型提升。

舉例

#include <stdio.h>
#include <stdarg.h>
void printargs(int arg1, ...) /* 輸出所有int類型的參數,直到-1結束 */
{
va_list ap;
int i;
va_start(ap, arg1);
for (i = arg1; i != -1; i = va_arg(ap, int))
printf("%d ", i);
va_end(ap);
putchar('\n');
}
int main(void)
{
printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
printargs(84, 51, -1);
printargs(-1);
printargs(1, -1);
return 0;
}
這個程式產生輸出:
5 2 14 84 97 15 24 48
84 51
1

頭檔案

POSIX定義所遺留下的頭檔案varargs.h,它早在C標準化前就已經開始使用了且提供類似stdarg.h的功能。MSDN明確指出這一頭檔案已經過時,完全被stdarg.h取代。這個頭檔案不屬於ISO C的一部分。檔案定義在單一UNIX規範的第二個版本中。
由於varargs.h不屬於標準C,所以不對其詳細說明。

相關詞條

熱門詞條

聯絡我們