| 修飾符 | 適用類型 | 說明 |
hh | %hhd, %hhu | signed char, unsigned char (C99) |
h | %hd, %hu | short, unsigned short |
l | %ld, %lu, %lf | long, unsigned long, double (scanf 必須) |
ll | %lld, %llu | long long (C99) |
L | %Lf, %Le, %Lg | long double |
z | %zd, %zu | size_t (C99) |
t | %td, %tu | ptrdiff_t (C99) |
j | %jd, %ju | intmax_t (C99) |
經典範例深度解析
- int main(){
- int a=15;
- float b=123.1234567;
- double c=12345678.1234567;
- char d='p';
- printf("a=%d,%5d,%o,%x\n",a,a,a,a);
- printf("b=%f,%lf,%5.4lf,%e\n",b,b,b,b);
- printf("c=%lf,%f,%8.4lf\n",c,c,c);
- printf("d=%c,%8c\n",d,d);
- }
逐行輸出分析
| 格式串 | 輸出結果 | 解析 |
%d | 15 | 預設十進制 |
%5d | 15 | 寬度 5,右對齊,前補 3 空格 |
%o | 17 | 八進制 15 = 17₈ |
%x | f | 十六進制 15 = f₁₆ |
%f | 123.123457 | 預設 6 位小數,四捨五入 |
%lf | 123.123457 | printf 中 %f/%lf 效果相同 |
%5.4lf | 123.1235 | 寬度 5 不夠,按實際輸出;小數 4 位四捨五入 |
%e | 1.231235e+02 | 指數形式 |
%8.4lf | 12345678.1235 | 雙精度完整精度,小數 4 位截斷 |
%8c | p | 寬度 8,字符前補 7 空格 |
⚠️ 核心陷阱:參數求值順序
C 標準未規定 printf 參數求值順序,不同編譯器可能不同!
- Turbo C / MSVC:從右向左求值
- GCC / Clang:通常從左向右求值(但不保證)
經典反面教材
- int i = 8;
- printf("%d\n%d\n%d\n%d\n%d\n%d\n", ++i, --i, i++, i--, -i++, -i--);
Turbo C (右→左) 輸出:
- 求值
-i--:輸出 -8,i→7
- 求值
-i++:輸出 -7,i→8
- 求值
i--:輸出 8,i→7
- 求值
i++:輸出 7,i→8
- 求值
--i:i→7,輸出 7
- 求值
++i:i→8,輸出 8
- 輸出順序仍左→右:8, 7, 7, 8, -7, -8
🚫 鐵律:printf 參數中絕對不要使用有副作用的表達式
// 錯誤示範
printf("%d %d", i++, i++); // 未定義行為!
// 正確做法:分離副作用
int a = i++;
int b = i++;
printf("%d %d", a, b);
進階實戰技巧
1. 動態寬度/精度控制
int w = 10, p = 4;
double pi = 3.1415926535;
printf("%*.*f\n", w, p, pi); // 等同於 printf("%10.4f\n", pi);
2. 字符串精度截斷
char *s = "Hello World";
printf("%.5s\n", s); // 輸出: Hello
3. 獲取已輸出字符數 (%n)
int count;
printf("Hello%n World\n", &count);
printf("前面輸出了 %d 字符\n", count); // 輸出: 5
4. 指針地址輸出
int x = 42;
printf("地址: %p\n", (void*)&x); // 標準要求 void* 轉換
printf 格式字串速查卡
| 需求 | 格式串範例 | 關鍵點 |
| 整數右對齊寬度 8 | %8d | 不足前補空格 |
| 整數左對齊寬度 8 | %-8d | - 旗標 |
| 整數補 0 寬度 6 | %06d | 0 旗標(數值類型) |
| 顯示正負號 | %+d | + 旗標 |
| 八進制帶前綴 | %#o | # 旗標 |
| 十六進制大寫帶前綴 | %#X | # + X |
| 浮點數固定 2 位小數 | %.2f | 精度 .2 |
| 浮點數寬度 10 精度 3 | %10.3f | 寬度.精度 |
| 科學計數法大寫 E | %E | 大寫 E |
| 自動選擇短格式 | %g | 去尾部 0 |
| 字符串最多 10 字符 | %.10s | 精度限制字串長度 |
總結
printf() 的格式字串系統極其強大,掌握 旗標、寬度、精度、長度、類型 五大修飾維度,能實現專業級的文本輸出格式化。但必須牢記參數求值順序未定義這一核心限制,絕不在參數中放置副作用表達式。現代 C 開發中,printf 仍是調試、日誌、CLI 工具的首選輸出方式,深入理解其機制是 C 程式員的必修功課。
- 上一篇文章: C語言格式輸入函數scanf()完整指南
- 下一篇文章: C語言字符輸入輸出函數getchar/putchar完整教學
Copyright ©
程式碼之家 All Rights Reserved