cout<a+<a;的正确答案是什么?

cout<a+<a;的正确答案是什么?

最近在一次采访中,有一个下面的客观类型的问题。

int a = 0;cout << a++ << a;

回答:

a.10
b.01
C.未界定的行为

我回答了选择b,即输出为“01”。

但令我惊讶的是,后来一位面试官告诉我,正确的答案是选项c:未定。

现在,我知道了C+中序列点的概念。以下语句未定义此行为:

int i = 0;i += i++ + i++;

但根据我对声明的理解cout << a++ << aostream.operator<<()会被调用两次,第一次是ostream.operator<<(a++)后来ostream.operator<<(a).

我还检查了VS 2010编译器的结果,它的输出也是‘01’。


HUWWW
浏览 830回答 3
3回答

神不在的星期二

你可以想到:cout&nbsp;<<&nbsp;a++&nbsp;<<&nbsp;a;作为:std::operator<<(std::operator<<(std::cout,&nbsp;a++),&nbsp;a);C+保证以前的评价的所有副作用都是在序列点..函数参数计算之间没有序列点,这意味着参数a可以在论证前进行评估std::operator<<(std::cout, a++)或者之后。因此,上述结果是未知的。C+17更新在C+17中,规则已经更新。特别是:在移位运算符表达式中E1<<E2和E1>>E2的每一个值计算和副作用E1的值计算和副作用之前对E2.这意味着它需要代码来生成结果。b,输出01.看见P0145R3修饰C+的表达式求值顺序更多细节。

12345678_0001

序列点只定义部分点菜。在您的情况下,您已经(一旦完成了重载解决):std::cout.operator<<(&nbsp;a++&nbsp;).operator<<(&nbsp;a&nbsp;);之间有一个序列点。a++第一次打电话到std::ostream::operator<<,在第二个a第二个电话是std::ostream::operator<<,但之间没有顺序点。a++和a;唯一的排序约束是a++在第一次调用之前对其进行全面评估(包括副作用)。operator<<,第二个a在第二个调用之前对其进行全面评估。operator<<..(也有一些谨慎的排序约束:第二个调用operator<<不能先于前者,因为它要求第一个结果作为一个参数。)§5/4(C+03)规定:除注意到的情况外,未具体说明单个运算符操作数的计算顺序和个别表达式的子表达式,以及产生副作用的顺序。在前一个序列点和下一个序列点之间,标量对象最多应该通过表达式的计算修改其存储值一次。此外,只能访问先前的值来确定要存储的值。对于一个完整表达式的子表达式的每一个允许的顺序,都应满足本款的要求;否则,该行为是不明确的。表达式的允许顺序之一是a++,&nbsp;a,第一个呼叫operator<<,第二次呼叫operator<<;这将修改a&nbsp;(a++),并访问它而不是确定新值(第二个a),行为是未定义的。
打开App,查看更多内容
随时随地看视频慕课网APP