printf、scanf 等函數參數個數不固定,C 標準庫提供 <stdarg.h> 宏實現可移植的變參處理。
#include <stdarg.h>
void demo(int fixed, ...) {
va_list ap; // 參數列表指標
va_start(ap, fixed); // 初始化,fixed 為最後一個固定參數
// 使用 va_arg(ap, type) 依序取得可變參數
va_end(ap); // 清理(某些平台需釋放資源)
}
#include <stdio.h>
#include <stdarg.h>
int Sum(int count, ...) {
va_list ap;
va_start(ap, count);
int sum = 0;
for (int i=0; i
va_start 的第二參數(定位棧幀)。printf 格式字串、首參數計數)。va_arg(ap, int) 取 float 會導致未定義行為(預設參數提升:float→double, char/short→int)。va_list 為單向,需重複使用時須 va_copy (C99) 或重新 va_start。char/short 實際為 int,float 為 double,取參時需用提升後型別。大多數架構下,參數在棧上連續分佈。va_list 實為 char* 指向第一個可變參數。va_arg 根據型別大小遞增指標並解引用。結構體參數可能按值傳遞(複製到棧)或傳址,取決於 ABI。
va_list ap, aq;
va_start(ap, count);
va_copy(aq, ap); // 複製狀態,可二次遍歷
// ... 使用 aq ...
va_end(aq);
va_end(ap);
vxxx 版本接受 va_list,方便包裝。-Wformat。變參函數是 C 語言靈活性的體現,但也帶來型別不安全風險,理解其棧幀操作機制與標準宏用法,是系統程式開發的必備技能。