风言枫语  

解析:
在这里声明,简单的比较前缀自增运算符和后缀自增运算符的效率是片面的,因为存在很多因素影响这个问题的答案。首先考虑内建数据类型的情况:如果自增运算表达式的结果没有被使用,而是仅仅简单的用于增加一员操作数,答案是明确的,前缀法和后缀法没有任何区别,编译器的处理都应该是相同的,很难想象得出有什么编译器实现可以别出心裁在二者之间制造任何差异。我们看看下面这个程序:
        #include <stdio.h>
        
        int main()
        {
                int i = 0;
                int x = 0;
        
                i++;
                ++i;
                x = i++;
                x = ++i;
        
                return 0;
        }
上面的代码在VC 6.0上编译得到的汇编如下:
; Line 5
        mov        DWORD PTR _i$[ebp], 0
; Line 6
        mov        DWORD PTR _x$[ebp], 0
; Line 8
        mov        eax, DWORD PTR _i$[ebp]
        add        eax, 1
        mov        DWORD PTR _i$[ebp], eax
; Line 9
        mov        ecx, DWORD PTR _i$[ebp]
        add        ecx, 1
        mov        DWORD PTR _i$[ebp], ecx
; Line 10
        mov        edx, DWORD PTR _i$[ebp]
        mov        DWORD PTR _x$[ebp], edx
        mov        eax, DWORD PTR _i$[ebp]
        add        eax, 1
        mov        DWORD PTR _i$[ebp], eax
; Line 11
        mov        ecx, DWORD PTR _i$[ebp]
        add        ecx, 1
        mov        DWORD PTR _i$[ebp], ecx
        mov        edx, DWORD PTR _i$[ebp]
        mov        DWORD PTR _x$[ebp], edx
代码段第8行和第9行生成的汇编代码分别对应Line 8和Line 9下对应的汇编代码,可以看到三个步骤几乎完全一样。
代码段第10行和第11行生成的汇编代码分别对应Line 10和Line 11下对应的汇编代码,可以看到都是五个步骤,只是在加1的先后顺序上有一些区别,效率也是完全一样的。
由此说明,考虑内建数据类型时,它们的效率差别不大(去除编译器优化的影响)。所以在这种情况下我们大可不必关心。
现在让我们再考虑自定义数据类型(主要是指类)的情况。此时我们不需要再做很多汇编代码的分析了,因为前缀式(++i)可以返回对象的引用,而后缀式(i++)必须产生一个临时对象保存更改前对象的值并返回(实现过自定义类型++运算符定义的就知道),所以导致在大对象的时候产生了较大的复制开销,引起效率降低,因此处理使用者自定义类型(注意不是指内建类型)的时候,应该尽可能的使用前缀式地增/递减,因为他天生体质较佳。
答案:
内建数据类型的情况,效率没有区别。
自定义数据类型的情况,++i效率较高。

posted on 2013-10-30 22:38  风言枫语  阅读(1657)  评论(0编辑  收藏  举报