代码改变世界

也说前自增和后自增

2013-10-29 06:43  Ross Wang  阅读(531)  评论(0编辑  收藏  举报

C++为什么不叫++C?来自:http://www.189works.com/article-42115-1.html

看到这个问题,觉得很有意思,回答它有助于理解前自增和后自增。

上面的帖子说得很清楚了:前自增得到的是对象执行完++之后的结果,是左值;后自增是得到对象当前值并给对象执行++,是右值。

那么现在来看这个问题:

++C:意思是得到了一个对C进行了扩充的对象(把执行自增看作就是对C进行了扩充),但是这个结果已经不是C了,那么就会有它是否还支持C的问题。

C++:意思是得到了C,并且对C进行了扩充,本身隐含了对C的完全支持,相比++C更能表示 “C++” 语言是 “C语言” 的超集事实。

 

另一个问题:当前自增和后自增都可以胜任的时候,我们如何选择呢?

比如下面的情况,MyClass 是我们自己定义的类型,当然我们重载了< 操作符和++操作符。

for( MyClass mc = oneMC; i < anotherMC; ++mc)
{}
for( MyClass mc = oneMC; i < anotherMC; mc++)
{}

如果MyClass比较复杂,其实例对象比较大,那么对于后自增来说,得到对象的当前值并给对象执行++,进而可能产生对象当前值一个副本。说可能是因为编译器可能对此作出优化。

所以,如果两者都可以用的时候,用前自增可以避免可能的对象拷贝时间开销和内存占用。

 

还有一个有趣的题

#include<iostream>
using namespace std;

int main()
{
    int i = 1;
    int j = ++i + ++i + ++i + ++i + ++i + ++i + ++i;
    cout<<j<<endl;
    return 0;
}

VS2010和Gcc 4.6下面的结果是不同的,前者输出56,后者输出36

原因分析:

VS2010的编译器在进行计算的时候,先把整个表达式(++i + ++i + ++i + ++i + ++i + ++i + ++i)入栈,然后依次出栈进行计算,入栈的时候++i被执行了7遍,最后的值为8,7个8相加56. (相当于采用右结合)

Gcc 4.6的编译器没有等到整个表达式都入栈才通过依次出栈进行计算,而是根据+操作符(二元)的左结合性,++i + ++i 的结果计算出来后再向表达式的右边计算;这样表达式执行第一次+运算的时候i已经执行了两次前自增了,所以相当于3 + 3,后面类似:

3 + 3 + 4 + 5 + 6 + 7 + 8 = 36

编译器行为不统一就说明标准在这里没有明确规定。具体到这个问题,就是连续执行+操作的时候,左结合还是右结合标准没有明确规定,编译器自己选择实现方式。