int printf(const char *format, ...); —— 固定參數 format 後跟不定個數/類型參數。
typedef char *va_list;
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
#define va_start(ap, v) (ap = (va_list)&v + _INTSIZEOF(v))
#define va_arg(ap, t) (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define va_end(ap) (ap = (va_list)0)
高地址
第 N 個可變參數
...
第 2 個可變參數
第 1 個可變參數 ← va_start 後 ap 指向這裡
固定參數 v
低地址
va_start(ap, v):以固定參數 v 地址為基準,加上 _INTSIZEOF(v)(按 sizeof(int) 對齊後的大小),得到第一個可變參數地址,賦給 ap。va_arg(ap, t):先將 ap 移動到下一個參數位置(ap += _INTSIZEOF(t)),再回退當前類型大小(- _INTSIZEOF(t)),強轉為 t* 解引用返回值。調用者必須知曉實際類型(如 printf 通過 format 解析)。va_end(ap):將 ap 置零,標記不可用。確保參數地址按 sizeof(int)(通常 4)對齊。例如 sizeof(n)=1~4 時對齊到 4;5~8 對齊到 8。
varargs.h 為 UNIX System V 風格,stdarg.h 為 ANSI C 風格,兩者不兼容,現代代碼應使用 stdarg.h。