关于对C语言掌握不细致造成的问题
问题67:让我们来玩“隐藏不露”
下面的程序在UNIX系统上会“倾倒”出系统浮点数除法错误。这让人很疑惑,因为我们的操作就根本没有涉及到浮点数操作。
为了找到问题的缘由,我们在部分地方安置了printf语句,用来观察程序在调用函数前到底发生了什么。但是我们的目的并没有得逞,因为我们根本看不到printf任何信息。(意译的)
1 /************************************************
2 * Compute a simple average. Because this *
3 * takes a long time (?) we output some *
4 * chatter as we progress through the system. *
5 ************************************************/
6 #include <stdio.h>
7
8 /************************************************
9 * average -- Compute the average given the *
10 * total of the series and the number *
11 * of items in the series. *
12 * *
13 * Returns: *
14 * The average. *
15 ************************************************/
16 int average(
17 const int total,// The total of the series
18 const int count // The number of items
19 )
20 {
21 return (total/count);
22 }
23
24 int main()
25 {
26 int ave; // Average of the number
27
28 printf("Starting....");
29 ave = average(32, 0);
30 printf("..done/n");
31
32 printf("The answer is %d/n", ave);
33 return (0);
34 }
//
//提示:缓冲区在哪?
//
//我的答案:
这个问题我还真没有回来出来,看了答案之后,才知道自己的水平相当的低,对C/c++理解还不是很深刻。废话不多说,没做出来的看看答案吧。
//
//标准答案:
printf函数是用内部缓冲区来存储要“打印”的东西的。它直到缓冲区满或者新行(/n)发生时它才会打印。
所以当问题程序进行到printf时候,"Starting"消息被送进了缓冲区但是并没有打印到屏幕上,下一个函数average接着运行,然后得到一个除零错误。
我们所看到的结果是"Starting"消息丢失了,进而以为average函数没有被调用。
解决的方法是输入消息后,明确的刷新缓冲区:
printf("Starting....");
fflush(stdout);
警告:缓冲区刷新的规则受到写入文件的类型的影响,这些规则是:
如果stdout 和 stderr是写入到屏幕的文件(应该值得就是写入到shell或console)的话,当新行写入、当stdin别读取、当缓冲区满应该刷新!
(这个规则不应该作为金科玉律死记硬背,真实的缓冲区刷新条件是与系统相关的)(作者意译的)
我在想c/c++的复杂不是没有道理的,最主要的是他与硬件的结合,让很多复杂的情况层出不穷。