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

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

概述我想知道两种形式的增量之间是否存在差异. links中有一些说我是i = i 1; 另外作为一个人我的观察也是一样的汇编代码.请检查图像,其中汇编代码对于i和i = i 1 – 还有另一个link说,以前以前增量运算符比加法和赋值更快,但现在编译器优化i和i = i 1是相同的. 有没有任何官方文件/论文,我们可以参考确认什么是正确的? (我通常会使用xyk和一个人在Stackoverflow上接 我想知道两种形式的增量之间是否存在差异. links中有一些说我是i = i 1;

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

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

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

解决方法 实际上,如果你做C,那么用来写我更好.原因很简单:我需要一份.
a = ++i; // a is set to the result of i+1a = 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 eaxADD eax,1                          ADD eax,1MOV (i),eax                        MOV (i),eax                                    POP eaxMOV (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 #00LOOP:    CLC    ADC (),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 – 了解更多关于i和i = i 1全部内容,希望文章能够帮你解决c – 了解更多关于i和i = i 1所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1251045.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存