混乱std :: cout的奇怪输出

时间:2011-04-19 21:40:35

标签: c++ std cout

C ++的std :: cout似乎是一件有趣的事情。我今天在C ++编译器上尝试了以下程序:

cout<<"!"<<"@"<<endl;
cout<<"!"<<cout<<"@"<<endl;
cout<<"!"<<(cout<<"@")<<endl;

输出很奇怪:

!@
!0x601068@
@!0x601068

第一行是行人;第二是可以理解的;然而,第三行是我所不知道的。有人可以解释输出吗?大家先谢谢你们!

Ziyao Wei

5 个答案:

答案 0 :(得分:5)

这一行:

cout<<"!"<<(cout<<"@")<<endl;

首先执行:

(cout << "@")

注意:它可能先执行其他操作,但编译器优化了这个子表达式,并发现它可以将其移动到语句的开头而不会破坏任何约束。

此表达式的结果是流(cout)。结果表达式是:

cout<<"!"<< cout <<endl;

这导致:

@!<pointer>

答案 1 :(得分:2)

与其他任何表达式(&lt;&lt;是运算符)一样,这些括号会影响评估顺序。由于表达式具有side-effects,因此这些副作用的发生顺序与表达式评估的顺序相同。

答案 2 :(得分:1)

第三行说明了作为插入算子的句法糖。

基本上首先评估(cout<<"@")表达式,得到@,它返回流本身cout

然后才会先!,然后将表达式发送到cout

相当于:

operator<<( operator<<( operator<<(cout,"!"), ( operator<<(cout,"@") ) ), endl);
                                                ^------------------^

突出显示的部分是一个表达式,必须在调用任何函数之前对其进行求值。

答案 3 :(得分:0)

我的假设 - 第3行中的括号使cout<<"@"先执行,这将@放在行的开头。然后cout.operator<<("!")执行,!就位。然后,ostream返回的cout.operator<<("!")运行其operator<<(),其中ostream返回cout<<"@",从而输出0x601068

答案 4 :(得分:0)

如果您了解第二行,为什么第三行会让您感到困惑?

首先,评估括号中的表达式(但未指定评估顺序),因此在标准输出上写入@;这样的表达式返回对cout的引用,就像插入运算符一样,因为否则它们无法链接。

现在表达式的这一部分被评估,一切都正常进行:行上的内容是从左到右写的:首先是!,然后从括号中的表达式返回的值(即引用cout,然后是endl