那本书是相当权威书。C99规定:
At program start-up, three text streams are predefined and need not be opened explicitly - standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output).
As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.
所以当标准输出被重定向到文件的话,是完全缓冲的。链接到终端的话,不是完全缓冲的。
但是,标准并没有规定是到底是那种模式,那是由实现定义的行为。
对于UNIX/Linux,终端是默认行缓冲的,这个是有历史原因的,和TTY(电传打字机)模式有关,当初那种主机-终端机的模式,如果每次打印一个字符或输入一个字符都要调用一次通信实在太慢了,所以标准输入输出都是行缓冲的。
而Windows的C库则是兼容的DOS里Microsoft C的行为,从MSDN里对于setvbuf的说明来看:
_IOLBF
For some systems, this provides line buffering. However, for Win32, the behavior is the same as _IOFBF - Full Buffering
.微软的CRT库不支持行缓冲模式(等同于完全缓冲),所以连接到终端的stdout"应该"是无缓冲的。
注意是应该,有趣的是从这篇知识库文章可知
http://support.microsoft.com/kb/44725/en-us
第一次调用printf时,16位应用程序会分配512字节标准I/O缓冲区,32位应用程序会分配4096字节。所以很奇怪,我有点儿怀疑那个”标准I/O缓冲区“是不是setvbuf里指的标准里的stdin、stdout缓冲区。
哪位有兴趣的,可以帮我测试一下在XP和Win7中,以及使用不同的MS编译器(早期的VS6.0,以及微软开始遵守C规范的2008、2010),那个程序的行为是否一致。也许默认缓冲行为会不一样。
#include "stdio.h"
int main()
{
int i;
printf("现在刷新了吗?");
for (i = 0; i<1000000000; i++);
printf("现在刷新了吗?");
for (i = 0; i<1000000000; i++);
printf("结束");
}