几天前,我在采访中问我的朋友,我遇到了一个小而令人讨厌的问题。
最初的面试问题是:“以下代码的输出是什么?”
int i = 2;
i = i++ + i++;正确的答案是((2 + 2) + 1) +1= 6,即后增量在赋值之前应用两次,但在加法之后。
然后,我想创建一个包含一个整数的简单类,并重载operator+()和operator++(int),以便在日志中查看执行运算符的确切顺序。
这是我得到的:
class A
{
public:
A(int _data) : data(_data) { }
A &operator=(const A& _rhs)
{
data = _rhs.data;
cout<<" -- assign: "<<data<<endl;
}
A operator++(int _unused)
{
A _tmp = data;
data++;
cout<<" -- post-increment: "<<data<<endl;
return _tmp;
}
A operator+(const A &_rhs)
{
A _tmp = data + _rhs.data;
cout<<" -- addition: "<<data<<"+"<<_rhs.data<<endl;
return _tmp;
}
inline operator int() const { return data; }
private:
int data;
};结果相当令人沮丧:
-- post-increment: 3
-- post-increment: 4
-- addition: 3+2
-- assign: 5对于不太复杂的结构,例如(A _dt2 = a++;),它的行为是正常的,但运算符的执行顺序与整型不同。
我猜这可能是编译器特有的问题:
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.所以,我有点迷路了:)
发布于 2011-10-27 19:07:57
最初的面试问题是:“以下代码的输出是什么?”
int i = 2;
i = i++ + i++;正确的答案是,因为您多次修改相同的变量,而其间没有序列点。
C++03标准§5 [expr] p4
除非另有说明,否则未指定单个运算符的操作数和单个表达式的子表达式的求值顺序,以及副作用发生的顺序。
这可能不能回答您真正的问题,但是即使您创建了一个类似整数的类并重载了operator++(int)和operator+(A const&),它也是相似的。函数的参数求值顺序是未指定的,可以按编译器喜欢的任何顺序执行,因此结果是未指定的。
发布于 2011-10-27 19:16:33
除了其他人已经指出的:孤立地看待你的问题的标题-“创建与整数类型完全相同的C++整数类”-我应该指出一个完全不同的原因,为什么它是 it 。
(据我所知)不可能用类模拟||和&&运算符的快捷行为,即操作数的两端无论如何都会被计算。
编辑:查看评论。“据我所知”似乎还不够。然而,Steve Jessop有一个不同的例子,使整个观点站得住脚。
这与你的增量问题完全无关,但与你的问题标题有关,所以我认为应该提到它。
发布于 2011-10-27 19:11:30
正确答案是((2 + 2) + 1) +1= 6,即后增量在赋值之前应用两次,但在加法之后。
这不是正确的答案:
除非另有说明,否则未指定单个运算符的操作数和单个表达式的子表达式的求值顺序,以及副作用发生的顺序。在前一个序列点和下一个序列点之间,标量对象的存储值最多只能通过表达式的求值修改一次。此外,应仅在确定要存储的值时访问先前值。对于完整表达式的子表达式的每个允许排序,应满足本段的要求;否则行为为undefined.
https://stackoverflow.com/questions/7914972
复制相似问题