原始代碼錯誤
printf("sum1=%d\n,sum1"); // 錯誤:格式字符串內包含變量名,實參缺失
printf("sum2=%d\n,sum2"); // 同理
現象:編譯可能通過 (僅警告),運行輸出 sum1=%d\n,sum1 字面文本,不顯示計算結果。
修正代碼
#include <stdio.h>
int main(void) {
int first = 30, second = 15;
int sum1 = first - second; // 差
int sum2 = first * second; // 積
printf("sum1=%d\n", sum1); // 修正:格式串與實參分離
printf("sum2=%d\n", sum2);
return 0;
}
核心知識點:printf 格式化輸出機制
| 組成 | 說明 | 示例 |
| 格式字符串 | 包含普通字符 (原樣輸出) 和轉換規格 (以 % 開頭) | "sum1=%d\n" |
| 轉換規格 | %[flags][width][.precision][length]type | %d 有符號十進制整數 |
| 實參列表 | 與轉換規格**一一對應**、類型匹配、順序一致 | sum1 對應 %d |
| 返回值 | 成功輸出的字符數,失敗返回負值 | 可用於檢查輸出是否成功 |
常見 printf 陷阱
- 格式串與實參分離錯誤:
printf("value=%d\n", value); ✅ vs printf("value=%d\n,value"); ❌
- 類型不匹配:
%d 對應 long/float/double/指針 → UB。long 用 %ld,float/double 用 %f/%lf (printf 中 %f 通用),指針用 %p。
- 實參數量不足:
printf("%d %d", a); → 讀取棧垃圾值,UB
- 實參數量過多:多餘實參被忽略 (但可能掩蓋邏輯錯誤)
- 字符串字面量合併:
printf("sum1=%d\n" "sum2=%d\n", sum1, sum2); ✅ 編譯期合併為單一字符串
編譯器輔助檢測
gcc -Wall -Wextra -Wformat=2 -Werror=format-security
# -Wformat=2 檢查格式串安全性 (如 %n)
# -Werror=format-security 將格式串漏洞升級為錯誤
總結
printf("format", args...) 中 **格式字符串與實參由逗號分隔**,格式串內**只能有轉換規格**,不能直接寫變量名。修正後輸出:
sum1=15
sum2=450
養成 **-Wall -Wextra -Wformat=2** 編譯習慣,在編譯期攔截 99% printf 類錯誤。
- 上一篇文章: C語言學習難度分析:邏輯思維、硬件認知與堅持是關鍵
- 下一篇文章: 如何高效學好 C 語言:從入門到精通的完整路徑與資源指南
Copyright ©
程式碼之家 All Rights Reserved