?
This document uses PHP Chinese website manual Release
變量函數是可以用不同數量的參數調用的函數。
只有新式(原型)函數聲明可能是可變的。這由...
必須出現在參數列表中的最后一個格式的參數表示,并且必須至少跟隨一個命名參數。
//New-style declarationint printx(const char* fmt, ...); // function declared this wayprintx("hello world"); // may be called with oneprintx("a=%d b=%d", a, b); // or more arguments // int printy(..., const char* fmt); // Error: ... must be the last// int printz(...); // Error: ... must follow at least one named parameter
在函數調用中,作為變量參數列表一部分的每個參數都會經歷特殊的隱式轉換,稱為默認參數促銷。
在使用可變參數的函數體內,可以使用<stdarg.h>庫函數來訪問這些參數的值:
| Defined in header <stdarg.h> |
|:----|
| va_start | 允許訪問可變參數函數參數(函數宏)|
| va_arg | 訪問下一個可變參數函數參數(函數宏)|
| va_copy(C99)| 制作可變參數函數參數(函數宏)|的副本
| va_end | 結束可變參數函數參數(函數宏)|的遍歷
| va_list | 保存va_start,va_arg,va_end和va_copy(typedef)所需的信息|
雖然舊式(無原型)函數聲明允許后續(xù)函數調用使用任意數量的參數,但它們不允許為可變參數(從C89開始)。這種函數的定義必須指定一個固定數量的參數,并且不能使用這些stdarg.h
宏。
//old-style declarationint printx(); // function declared this wayprintx("hello world"); // may be called with oneprintx("a=%d b=%d", a, b); // or more arguments// the behavior of one of these calls is undefined, depending on// whether the function is defined to take 1 or 3 parameters
#include <stdio.h>#include <time.h>#include <stdarg.h> void tlog(const char* fmt,...){ char msg[50]; strftime(msg, sizeof msg, "%T", localtime(&(time_t){time(NULL)})); printf("[%s] ", msg); va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args);} int main(void){ tlog("logging %d %d %d...\n", 1, 2, 3);}
輸出:
[10:21:38] logging 1 2 3...
C11標準(ISO / IEC 9899:2011):
6.7.6.3/9函數聲明符(包括原型)(p:133)
7.16變量參數<stdarg.h>(p:269-272)
C99標準(ISO / IEC 9899:1999):
6.7.5.3/9函數聲明符(包括原型)(p:119)
7.15變量參數<stdarg.h>(p:249-252)
C89 / C90標準(ISO / IEC 9899:1990):
3.5.4.3/5函數聲明符(包括原型)
4.8變量<stdarg.h>