在循环语句中,for(i=0;i<n;i++)和for(i=0;i<n;++i)有什么区别?
我同学有简单地告诉我,i++的话要先copy出一个i然后赋值,用原来的i继续其他运算,最后再把copy出来的i做个increment,然后返还给原来的i。
而++i直接在原来的i上做increment。
结论:当n很大的时候,++i速度比i++快。
比如语法上a = i++; 是等号右边的变量赋值给左边的变量,但是赋值应发生在所有运算之后。这就比较矛盾,如果用上诉理论就能解释得清楚。
请问他说的对吗?
按时间排序 默认排序
17 个回答
知乎用户 时刻都要保持优雅
这个问题把我们送回了80年代那个勒紧裤腰带开发程序的日子,多两三条代码程序会慢到死吗,我相信现在已经不是主要问题了,就算出现问题,那也是编译器作者的问题,不是程序员的问题。
隼之心 活着就是最好的
只是人的习惯问题,就好比为什么每个语言第一个程序叫hello world而不是hello monkey
Yi Zhao 资深学渣
加一段timer不就知道了么,我只记得老师说不管是++i还是i++都比i=i+1快,i++在n十分大的时候慢于++i,原理早忘了(或许应该查看下汇编)
宁绪 灵魂黑客兼画师,以前曾是一名Android De…
学校里就讲到++i先将i加一再运算,i++把原值运算后再加一,好low,突然感觉。。。。。。
嘛咪嘛咪哄 软件工程师,喜自由自在,趣味广
测试一下
徐辰 C++ is nothing about OOP
在C++里,假如i是int,那么没有任何不同,无论开不开优化,你没有使用自增后的i值,编译器根本就不会“复制”一个i。
如果i是个自定义类型,又自定义了前缀和后缀++操作符,那自然是不一样的。
知乎用户 都看到这里了,关注一下吧。
本来,这样的问题我不会回答,心里说“编译器君掩面不语”后跳到下一个问题。
但是冲着你的第一句话:“(这个问题估计1万个程序员也不到1个能真正领悟)”。我忍不住进来跟你说,同学,你一定要成为一个万里挑一的程序员啊。
Gomo Psivarh 码见 / RetroGame / 日麻 / LoveLive
我想说的是现在已经是2015年了,编译器都发展了几十年了连这点优化都做不到也好意思拿得出来?程序优化的重点应该放在项目的性能瓶颈上,而不是抠这种几乎无意义的细枝末节。
再说了,如果你非觉得编译器不可信非要写成++i,那我可以告诉你把
for(int i=0; i<n; ++i)
写成
for(int i=n-1; i>=0; --i)
会更快(汇编可以少一个CMP指令,当然主流的编译器基本都会自动帮你做这样的优化)
你会把程序中所有循环改成下面那种吗?
知乎用户 计算机吐槽学
按C来说
i++把i增加1,返回i增加前的值
至于是先计算整个表达式还是先增加i应该是未定义的
++i先把i加1,返回i的引用
在for里i++和++i由于返回值没有被使用,因此会被优化成一样的结果
孙明琦 会用几门语言写helloworld
不开优化,并没有什么不同
开启优化,编译器是不会在这种地方拖慢你的程序的
能把循环内的乘法优化成两个add指令,循环本身的跳转也大大简化
优化之后的代码已经看不到所谓的i++和++i了
(哪位聚聚能给解释一下那两个add指令是如何变成乘法的)
有些人就是不肯平心静气地和人说话,是吧
Merci飞来飞去 王阳明
i++返回的是i本身的值,++i返回的是i+1的值,可以写一个小程序测试一下就知道了。
颢凡 再浪一年
for循环中不好说明,不妨假设有这样一个表达式:
int i = 3;
int k;
k = ++i; //#1
k = i++; //#2
前置递增运算符:对象递增加一再使用
即:
/* #1等价于 */
i = i+1; //i的值为4
k = i; //k 的值为4
后置递增运算符:创建一个临时对象,将临时对象替换调用原变量的位置,原变量+1
即:
/* #2等价于 */
k = int(i); //int(i) 是一个临时对象,值为4
i = i+1; //i 的值为5
也就是说后置递增相比前置递增会创建一个临时对象int(i),使用临时对象赋值给k,所以后置递增会比前置递增慢那么一丢丢。
知乎用户 德国队/拜仁粉/幼儿期码农
习惯用++i,但我相信编译器对此的优化,不会在意它的性能。
对于a = i++;那段,我不大清楚你的问题,不知道下面这样说能不能帮你理解。
你说的“等号右边的变量赋值给左边的变量”,那既然是“值”,这个值也就可以来自于另外一个变量(假设是t),t保存了i自增前的值,然后把t返回给了左边进行赋值操作。
把++理解成下面这个方法。
int jiajia(int &i)
{
int t = i;
i += 1;
return t;
}
a = i++;就变成了a = jiajia(i);
panszAndroid 开发、Linux话题优秀回答者 我说的大多是一…
如果 i 是系统类型,两者没有性能区别。绝大多数编译器可以生成同效率代码。由于所谓的多余复制的变量并没有被用到(i++的返回值无人使用),所以编译器优化之后跟++i等价。
两者性能区别理论上存在于当 i 是一个自定义的类,并且这个类重载了++操作符,并且这个类重载「后增量」操作符时使用了值复制作为返回值的情况,在这种情况下,有时编译器能优化掉多余的复制,有时不能。所以++对于自定义对象类型来说会有题主所说的情况。
毛草 软件工程师/MBA在读/考虑创业/动漫宅/单…
所有支持++的语言中,按定义++i的速度一定大于等于i++
薛非 《品悟C》作者
在循环语句中,for(i=0;i<n;i++)和for(i=0;i<n;++i)有什么区别?
没。
我同学有简单地告诉我,i++的话要先copy出一个i然后赋值,用原来的i继续其他运算,最后再把copy出来的i做个increment,然后返还给原来的i。
而++i直接在原来的i上做increment。
无依据的臆测。
比如语法上a = i++; 是等号右边的变量赋值给左边的变量,但是赋值应发生在所有运算之后。
错。
====================================
做点正事,不要问没有意义的问题。
现代程序设计不怎么追求速度,通常认为代码可读性优先于程序效率。
即使要求效率也是从算法和数据结构入手,
从for语句中挖掘速度无异于从牙缝里找吃的希望吃的更饱些。
Intopass Java Developer Learning C++
一:i++ 和 ++i
从Java的角度来说,这两个没有区别。(证据,生成的字节码一样。)
从C/C++的角度来说,++i可能更好一些,因为不用存储一个中间变量。(但我怀疑这个是可以被编译器优化掉的。)
二:运算顺序
讨论一个语句中如,i = i++ + i++。究竟++操作是何时发生的,对于C/C++语言可能没有意义,因为是未定义行为,对于Java来说是有意义,因为Java明确定义了运算顺序。