混合的奇怪输出 std::cout

Strange outputs of mixed up std::cout

本文关键字:std cout 输出 混合      更新时间:2023-10-16

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

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

输出相当奇怪:

!@
!0x601068@
@!0x601068
第一条线是

行人;第二条线是可以理解的;然而,第三条线超出了我的知识范围。有人可以解释输出吗?提前谢谢大家!

魏子耀

这一行:

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

它首先执行:

(cout << "@")

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

此表达式的结果是一个流 (cout(。所以得到的表达式是:

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

这导致:

@!<pointer>
括号

会影响此处的计算顺序,就像在任何其他表达式中一样(<<是运算符(。 由于表达式具有副作用,因此这些副作用的发生顺序与表达式计算的顺序相同。

这第三行说明了作为插入运算符的语法糖。

本质上,(cout<<"@")表达式首先被计算,从而产生@,它返回流cout本身。

只有这样,!才会先发送,然后是表达式,然后是表达式,然后发送到cout

它相当于:

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

突出显示的部分是在调用任何函数之前必须计算的表达式。

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

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

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

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