立即注册 登录
一牛网 返回首页

miaossaiche的个人空间 http://bbs.16rd.com/?87300 [收藏] [复制] [RSS]

日志

《C语言基础》为什么 ++i 的效率比 i++ 高

已有 1447 次阅读2019-9-25 19:40 |个人分类:C语言|系统分类:基础知识| c语言

前言
为什么说 ++i 的效率比 i++ 高?看完这篇文章,你就能找到答案

++i与i++的区别

这两个表达式从我们初学编程语言的时候就会接触到。前者是自增后取值,后者是取值后自增

我们看一个简单的例子。

#include<IOStream>

usingnamespacestd;

intmain

{

inta = 0;

intb = 0;

intc = a++; //int tmp = a;c=a;a = a + 1

intd = ++b; //b = b + 1;d = b;

cout<< "c="<

return0;

}

运行结果:

c= 0;d= 1

对于这个结果我们并不感到意外。

另外我们还注意到另外一个有意思的现象:

#include<iostream>

usingnamespacestd;

intmain

{

inta = 0;

intb = 0;

int*c = &(a++);

int*d = &(++b);

return0;

}

编译后报错:

main.cpp: 7: 19: error: lvalue required asunary ‘&’ operand

int*c = &(a++);

说&作用于左值,也就是说a++的结果并非左值。但++b的结果是左值。

可简单理解左值和右值:

左值,有名对象,可赋值

右值,临时对象,不可被赋值

为什么说 ++i 的效率比 i++ 高?看完这篇文章,你就能找到答案

运算符重载

在《运算符重载》一文中已经说到了运算符的重载,通过前面的例子也发现了,对于内置类型,前置自增返回对象的引用,而后置自增返回对象的原值(但非左值)。

基于上述原则,一个前置版本和后置版本的常见实现如下:

classTest

{

public:

Test& operator++; //前置自增

constTest operator++( int); //后置自增

private:

intcurPos; //当前位置

};

/*前置自增实现范式*/

Test& Test:: operator++

{

++curPos; //自增

return* this; //取值

}

/*后置自增实现范式,为了与前置区分开,多了一个int参数,但从来没用过*/

constTest Test:: operator++( int)

{

Test tmp = * this; //取值

++curPos; //自增

returntmp;

}

仔细观察后,我们发现前置自增,先自增,后返回原对象的对象;没有产生任何临时对象;而后置自增,先保存原对象,然后自增,最后返回该原临时对象,那么它就需要创建和销毁,这样一来,效率孰高孰低就很清楚了。

在不进行赋值的情况下,内置类型前置和后置自增的汇编都是一样的呢!

voidtest

{

inti = 0;

i++;

//++i;

}

汇编:

push rbp

mov rbp, rsp

mov DWORD PTR [rbp-4], 0

add DWORD PTR [rbp-4], 1

nop

pop rbp

ret

不过,赋值的情况下,并且不开启编译器优化,它们的汇编代码还是有差别的,有兴趣的可以试试。

为什么说 ++i 的效率比 i++ 高?看完这篇文章,你就能找到答案

总结

对于内置类型,前置和后置自增或者自减在编译器优化的情况下,两者并无多大差别,而对于自定义类型,如无特别需要,人们似乎更加偏爱前置自增或自减,因为后置自增常常会产生临时对象。

但是,又能提高多少效率呢?你怎么看?


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

联系我们|小黑屋