當函數參數個數不固定時,即為可變參數。經典案例是 printf:
int printf(const char *format, ...);
定義於 <stdarg.h>,包含:
va_list:參數列表指針類型va_start(va_list ap, paramN):初始化,定位至首個可變參數va_arg(va_list ap, type):按指定類型取出下一個參數va_end(va_list ap):清理,將 ap 置空va_list ap;va_start(ap, 最後一個固定參數)va_arg(ap, 期望類型) 取值va_end(ap) 收尾#include <stdio.h>
#include <stdarg.h>
#define END -1
int va_sum(int first_num, ...) {
va_list ap;
va_start(ap, first_num);
int result = first_num;
int temp;
while ((temp = va_arg(ap, int)) != END) {
result += temp;
}
va_end(ap);
return result;
}
int main() {
printf("%d\n", va_sum(1, 2, 3, 4, 5, END)); // 輸出 15
return 0;
}
va_list 本質是 char*,指向棧上參數區va_start 利用固定參數地址加上其對齊後大小,定位首個可變參數va_arg 先將指針前移下一參數大小,再回退取值va_end 將指針置零,防止誤用_INTSIZEOF(n) 宏確保參數按 int 倍數對齊#include <stdarg.h>END 或 printf 的格式字串),va_arg 無法自動檢測結尾vsprintf/vprintf 族函數register、函數或陣列類型