前言
调试一些短小的程序的时候,一般会用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同样遵循了这个规则,在内核中程序是不会终止的,这个时候就必须要加上换行符,否则就会看不到输出,哈哈,如果忘了加,可能就需要重新编译内核!