转自:http://blog.csdn.net/julysee/article/details/43760205
今天网上看到一个华为的面试题目:
写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值
int a = 4;(A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++);
答案是C是错误的,而A B D是正确的。
我感到很疑惑,于是敲代码验证下,在C++中,确实答案是C不正确。但是在C中,C与D都是错误的。这就非常奇怪了,为什么会这有这样的区别,原因在什么地方呢?
想要知道答案,只能求助于经典书籍了。
C部分
在《C和指针》5.1 操作符中,有这么一段描述:
int a, b, c, d;
...
a = b = 10; a和b得到值10
c = ++a; a增加到11,c得到的值为11
d = b++; b增加到11,d得到的值为10
抽象地说,前缀和后缀形式的增值操作符都是复制一份变量值的拷贝。用于周围表达式的值正是这份拷贝(在上面的例子中,周围表达式是指赋值操作)。前缀操作符在进行复制之前增加变量的值,后缀表达式在进行复制之后才增加变量的值。这些操作符的结果不是被它们所修改的变量,而是变量值的拷贝,认识这一点非常重要。它之所以重要是因为它解释了你为什么不能像下面这样使用这些操作符:
++a = 10;
++a的结果是a值得拷贝,并不是本身变量,你无法向一个值进行赋值。
C++部分
在《c++ primer 4th》5.5 自增自减操作符中有以下描述:
自增(++)和自减(--)操作符为对象加1 或减1 操作提供了方便简短的实现方式。它们有前置和后置两种使用形式。到目前为止,我们已经使用过前自增操作,该操作使其操作数加1,操作结果是修改后的值。同理,前自减操作使其操作数减 1。这两种操作符的后置形式同样对其操作数加 1(或减 1),但操作后产生操作数原来的、未修改的值作为表达式的结果:
int i = 0, j;
j = ++i; // j = 1, i = 1: prefix yields incremented value
j = i++; // j = 1, i = 2: postfix yields unincremented value
因为前置操作返回加1 后的值,所以返回对象本身,这是左值。而后置操作返回的则是右值。
这两段文字就可以解决我们的疑惑了。