C ++的std :: cout似乎是一件有趣的事情。我今天在C ++编译器上尝试了以下程序:
cout<<"!"<<"@"<<endl;
cout<<"!"<<cout<<"@"<<endl;
cout<<"!"<<(cout<<"@")<<endl;
输出很奇怪:
!@
!0x601068@
@!0x601068
第一行是行人;第二是可以理解的;然而,第三行是我所不知道的。有人可以解释输出吗?大家先谢谢你们!
答案 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
。