为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++ C
HUWWW 2019-07-20 12:36:34
cout<a+<a;的正确答案是什么?最近在一次采访中,有一个下面的客观类型的问题。int a = 0;cout << a++ << a;回答:a.10b.01C.未界定的行为我回答了选择b,即输出为“01”。但令我惊讶的是,后来一位面试官告诉我,正确的答案是选项c:未定。现在,我知道了C+中序列点的概念。以下语句未定义此行为:int i = 0;i += i++ + i++;但根据我对声明的理解cout << a++ << a,ostream.operator<<()会被调用两次,第一次是ostream.operator<<(a++)后来ostream.operator<<(a).我还检查了VS 2010编译器的结果,它的输出也是‘01’。
查看完整描述

3 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

你可以想到:

cout << a++ << a;

作为:

std::operator<<(std::operator<<(std::cout, a++), a);

C+保证以前的评价的所有副作用都是在序列点..函数参数计算之间没有序列点,这意味着参数a可以在论证前进行评估std::operator<<(std::cout, a++)或者之后。因此,上述结果是未知的。


C+17更新

在C+17中,规则已经更新。特别是:

在移位运算符表达式中E1<<E2E1>>E2的每一个值计算和副作用E1的值计算和副作用之前对E2.

这意味着它需要代码来生成结果。b,输出01.

看见P0145R3修饰C+的表达式求值顺序更多细节。


查看完整回答
反对 回复 2019-07-20
?
12345678_0001

TA贡献1802条经验 获得超5个赞

序列点只定义部分点菜。在您的情况下,您已经(一旦完成了重载解决):

std::cout.operator<<( a++ ).operator<<( a );

之间有一个序列点。a++第一次打电话到std::ostream::operator<<,在第二个a第二个电话是std::ostream::operator<<,但之间没有顺序点。a++a;唯一的排序约束是a++在第一次调用之前对其进行全面评估(包括副作用)。operator<<,第二个a在第二个调用之前对其进行全面评估。operator<<..(也有一些谨慎的排序约束:第二个调用operator<<不能先于前者,因为它要求第一个结果作为一个参数。)§5/4(C+03)规定:

除注意到的情况外,未具体说明单个运算符操作数的计算顺序和个别表达式的子表达式,以及产生副作用的顺序。在前一个序列点和下一个序列点之间,标量对象最多应该通过表达式的计算修改其存储值一次。此外,只能访问先前的值来确定要存储的值。对于一个完整表达式的子表达式的每一个允许的顺序,都应满足本款的要求;否则,该行为是不明确的。

表达式的允许顺序之一是a++a,第一个呼叫operator<<,第二次呼叫operator<<;这将修改a (a++),并访问它而不是确定新值(第二个a),行为是未定义的。


查看完整回答
反对 回复 2019-07-20
  • 3 回答
  • 0 关注
  • 829 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信