編譯器如何檢查 printf 參數個數?為何格式字串與參數不匹配時編譯器不報錯(僅警告)?
C 語言透過 stdarg.h 宏實現可變參數:
va_list:參數指標,指向棧上第一個可變參數。va_start(ap, last_fixed):初始化 ap 指向第一個可變參數。va_arg(ap, type):取得當前參數並移動指標到下一個。va_end(ap):清理。format),掃描 % 格式指示符。%d、%s 等)決定預期參數型別與個數。va_arg 從棧上取出對應大小的資料。-Wformat),無法在編譯期強制阻止。void myprintf(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
while (*fmt) {
if (*fmt == '%') {
fmt++;
switch (*fmt) {
case 'd': printf("%d", va_arg(ap, int)); break;
case 's': printf("%s", va_arg(ap, char*)); break;
// ...
}
} else {
putchar(*fmt);
}
fmt++;
}
va_end(ap);
}
va_start 利用最後一個固定參數位址計算第一個可變參數位址。-Wall -Wformat=2(GCC/Clang)或 /W4(MSVC)捕捉格式不匹配。fmt 庫替代 printf,獲得型別安全。