前言
調試一些短小的程序的時候,一般會用printf等輸出一些有用信息,以粗略的定位Bug的位置!作為學習C語言甚至剛接觸計算機開始,就認識的printf函數,可能我們已經非常的熟悉其使用了,雖然對其底層格式化輸出的原理知之甚少,對整個執行流程似懂非懂。
不知道你是否曾經遇到過printf失靈的情況,即本應該打印數據,卻沒有任何輸出信息?這個時候你可能首先懷疑,printf之前的程序除了問題,可能出現了死鎖,或者死循環等:
#include <stdio.h>
int main(void) {
while (1);
printf("Hello World!");
return 0;
}
但是如果我們把這個程序,稍加修改呢?
#include <stdio.h>
int main(void) {
printf("Hello World!");
while (1);
return 0;
}
你會發現,依然沒有任何輸出!
(必須是Linux 環境,win中是有輸出的,兩者的實現不同,我們主要考慮Linux環境)
printf 的輸出條件
你可能從來沒聽過,printf輸出,居然還有條件,這是在《C prime Plus 第五版》中學習到的,當時的我也同樣驚訝。直到前不久,同窗的學妹同樣表示了驚訝,所以我決定分享這個小知識,printf在滿足以下三個條件之一時,會將緩沖區中的數據輸出:
- 需要換行符
\n
- printf的緩沖區滿
- 程序終止
即:
int main(void) {
printf("Hello World\n");
for(;;);
return 0;
}
或
int main(void) {
for(;;)
printf("Hello World");
return 0;
}
或
int main(void) {
printf("Hello World\n");
for(;;);
}
其中1、3情況,是我們在絕大多數時候會使用的,因此在絕大部分情況下,你都不會察覺到printf的“異常”。
緩沖區有多大?
1KB,可以自己寫程序驗證
后記
雖然是很簡單的小知識,但是有時候真的非常有用,比如在調試linux內核時,使用的printk同樣遵循了這個規則,在內核中程序是不會終止的,這個時候就必須要加上換行符,否則就會看不到輸出,哈哈,如果忘了加,可能就需要重新編譯內核!