c – 了解更多关于i和i = i 1

前端之家收集整理的这篇文章主要介绍了c – 了解更多关于i和i = i 1前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道两种形式的增量之间是否存在差异. links中有一些说我是i = i 1;

另外作为一个人我的观察也是一样的汇编代码.请检查图像,其中汇编代码对于i和i = i 1 –

还有另一个link说,以前以前增量运算符比加法和赋值更快,但现在编译器优化i和i = i 1是相同的.

有没有任何官方文件/论文,我们可以参考确认什么是正确的? (我通常会使用信用卡和一个人在Stackoverflow上接受的答案,在我提供的链接上找不到这样的东西).

解决方法

实际上,如果你做C,那么用来写我更好.原因很简单:我需要一份.
a = ++i; // a is set to the result of i+1
a = i++; // make a copy of i,compute i+1,save the copy of i in a

没有优化,汇编代码将如下所示:

a = ++i;                            a = i++;

MOV eax,(i)                        MOV eax,(i)
                                    PUSH eax
ADD eax,1                          ADD eax,1
MOV (i),eax                        MOV (i),eax
                                    POP eax
MOV (a),eax                        MOV (a),eax

现在,通过优化,结果与C中相同,其中运算符仅适用于整数和指针.

和 – 在那里,因为大多数处理器在写入C时有一个INC和一个DEC指令.所以如果要使用索引寄存器,这些指令将被应用:

char a[256];
...init 'a' in some way...
int sum =0;
for(int i = 0; i < 100; ++i)
{
    sum += a[i];
}

这可以用(6502)中的简单INC来完成:

LDA #00
    LDY #00
LOOP:
    CLC
    ADC ($80),Y
    INY              <-- ++i or i++
    CPY #100
    BCC LOOP

请注意,在C中,我们有另一个符号来增加一个变量:

i += 1;

如果您需要将寄存器增加1以上,这是实用的:

i += 3;

或者每次加倍注册

i += i;   // (equivalent to  i *= 2;  or  i <<= 1;  in C++)

问题:为什么INC和DEC不与所有80×86一起使用?

有一段时间,ADD reg,1和SUB reg,1指令比INC reg和DEC reg更快.在过去,它更快,因为指令较小,我们没有缓存(或很少).今天,任何一条指令可能大致相同.

从下面的评论来看,FLAGS注册表的“缓慢”原因是:

Intel Optimization Reference,section 3.5.1.1 Use of the INC and DEC Instructions

从另一个更新的评论来看,它看起来像是在较新的处理器中修正了英特尔文档的缓慢.因此,使用或不使用这些指令应取决于目标处理器,如果事先知道的话.

正如phresnel在评论中指出的那样,我和我之间的区别对许多人来说可能不清楚.对于一个整数,优化是非常微不足道的,绝对会发生,甚至是使用-O0.然而,这是一个不同的故事.有一个类,两个增量运算符清楚地表明我需要一个副本(即使data_只是一个整数,尽管在这种情况下你也可以做:return data_ – 它仍然需要一个很好的隐藏的副本!):

class A
{
public:
    A& operator ++ () // ++i -- no copy
    {
        ...apply the ++ operation to 'data_'...
        return *this;    // return a reference to this
    }

    A  operator ++ (int) // i++ -- needs a temporary copy
    {
        // remember that the 'int' is totally ignored in the function,// its only purpose is to distinguish '++i' from 'i++'

        A copy = *this;    // here we need a copy
        ++*this;
        return copy;       // and here we return said copy
    }

private:
    some_type_t   data_;
};

请注意,现代C编译器不会在i函数生成两个副本,因为可以优化返回值,无需额外的副本.

如果使用i,如Is there a performance difference between i++ and ++i in C++?(phresnel提到的链接),两种情况之间的差异可以明显较慢

猜你在找的C&C++相关文章