我知道cout和printf今天有缓冲区,据说缓冲区有点像堆栈,从右到左得到cout和printf的输出,然后从顶部输出(到控制台或文件)到了僵尸。像这样,
a = 1; b = 2; c = 3;
cout<<a<<b<<c<<endl;
buffer:|3|2|1|<- (take “<-” as a poniter)
output:|3|2|<- (output 1)
|3|<- (output 2)
|<- (output 3)
然后我写下面的代码,
#include <iostream>
using namespace std;
int c = 6;
int f()
{
c+=1;
return c;
}
int main()
{
int i = 0;
cout <<"i="<<i<<" i++="<<i++<<" i--="<<i--<<endl;
i = 0;
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
cout<<f()<<" "<<f()<<" "<<f()<<endl;
c = 6;
printf("%d %d %d\n" , f() , f() ,f() );
system("pause");
return 0;
}
在VS2005下,输出为
i=0 i++=-1 i--=0
i=0 i++=-1 i--=0
9 8 7
9 8 7
在g ++((GCC)3.4.2(mingw-special))下,输出是,
i=0 i++=0 i--=1
i=0 i++=-1 i--=0
9 8 7
9 8 7
似乎缓冲区就像一个堆栈。但是,我今天读了 C ++ Primer Plus ,据说cout从左到右工作,每次都返回一个对象(cout),所以“这就是让你通过使用连接输出的功能插入”。但从左到右的方式无法解释cout&lt;输出9 8 7 现在我对cout缓冲区如何工作感到困惑,有人可以帮助我吗?
答案 0 :(得分:6)
输出:
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
未指定。这是C ++的常见缺陷:参数评估顺序未指定。
cout案例不是这样:它使用链式调用(序列点),而不是单个函数的参数,因此评估顺序从左到右定义良好。
编辑:David Thornley指出上述代码的行为实际上是 undefined 。
答案 1 :(得分:3)
这不是错误,也不是与输出缓冲有关。
i--
和i++
操作的执行顺序在多次作为同一函数调用的参数调用时未定义。
为了详细说明(并且可能正确)Iraimbilanja提到的“序列点”,cout
版本相当于:
(((cout << a) << b) << c)
实际上,它实际上是三个独立的函数调用,每个函数调用的顺序都按顺序进行评估,即使它被写成单个语句。
<<
运算符实际上是ostream& operator<<(ostream& os, int)
,因此另一种写法是:
operator<< ( operator<< ( operator<< ( cout, a ), b ), c )
因为外部调用不是(AFAIK)定义了两个参数的评估顺序,所以右边的“c”参数(或者在你的情况下为“i--
”)完全可能发生评估左手参数。
答案 2 :(得分:0)
如果可能的话尝试更新到gcc&gt; = 4.我刚刚在4.0.1上运行它,它只执行花花公子。