回答
它们几乎相同。唯一的区别是i
仅在+=
的情况下评估一次,而在另一种情况下则为两次。
而'i + = j'更具可读性:) – VoidPointer
'i'必须在第二种情况下评估两次,而不是第一次?我并不完全遵循你的逻辑,并且很想听听你是怎么想出来的。 –
@MichaelDorgan通常它不会有问题(因为'i'会填入某个寄存器中,所以会被优化),但是如果'i'是易失性的并且被其他线程或中断修改,可能会引起关注。希望_still_无关紧要,因为你已经适当地确保[互斥](http://en.wikipedia.org/wiki/Mutual_exclusion),以便只有一个执行单元一次访问它。 –
i = i + j
是相当于到i += j
但不相同。
在某些情况下(罕见)i += j
与i = i + j
不同,因为i
本身有一个side effect。
还多了一个问题是operator precedence即
i = i * j + k;
不一样
i *= j + k;
最完整的答案,+1。 –
+1我的设置与'gcc -O0 -S'完全没有什么区别。 – jman
尝试使用更复杂的'i'表达式。 –
几乎没有差别,但如果i
是一个复杂的表达式,它仅计算一次。假设你有:
int ia[] = {1, 2, 3, 4, 5};
int *pi = &(ia[0]); // Yes, I know. I could just have written pi = ia;
*pi++ += 10;
// ia now is {11, 2, 3, 4, 5}.
// pi now points to ia[1].
// Note this would be undefined behavior:
*pi++ = *pi++ + 10;
两种说法i = i + j
和i += j
,在功能上相同,在第一种情况下,你使用的是一般的赋值操作,而第二个使用combinatorial assignment operator
。 +=
是additive assignment operator
(添加后跟赋值)。 组合赋值运算符的使用生成smaller source code
即less susceptible to maintenance errors
,也可能是smaller object code
,运行速度也会更快。 Compilation is also likely to be a little faster
。
在两种情况下,i
(所分配的变量或表达式)必须是左值。在大多数简单情况下,只要i
未被声明为volatile
,这将产生在两种情况下都相同的代码。
但是有一些情况下,左值可能是涉及运算符的表达式,这可能导致两次评估i
。可能以这种方式被用于一个左值表达的最合理的例子也许是一个指针的简单解引用(*p
):
*p = *p + j ;
*p += j ;
可以生成不同的代码,但它是平凡优化,所以我期望不即使没有已启用优化。再次p
不能是volatile
,否则表达式在语义上是不同的。
一个不太合理的情况是使用条件运算符表达式作为左值。例如,下面的补充j
到b
或c
取决于a
:
(a ? b : c) += j ;
(a ? b : c) = (a ? b : c) + j ;
这些可能产生不同的代码 - 编译器可能无法合理发现习语和应用的优化。如果表达式a
有副作用 - 例如是表达getchar() == '\n'
或a
是volatile
(不管b
或c
),那么它们不是等效由于第二将评估为:
c = b + j
用于输入"Y\n"
,b = b + j
输入"\n\n"
,c = c + j
输入"YN"
。
这些问题当然大多是无关紧要的 - 如果你写这样的代码,它做了你没想到的事情,同情可能会供不应求!
- 1. while(++ i < - j)&while(i ++ <j--)有什么区别?
- 2. 在MATLAB中使用(j,i)与(i,j)之间的区别
- 3. 有可能对于两个正整数i和j,(-i)/ j不等于 - (i/j)?
- 4. i ++和++ i有什么区别?
- 5. 根据c标准j = i ++ * i ++是未定义的,但j = i ++&i ++是合法的,为什么?
- 6. --i和i--有什么区别?
- 7. 如何在Numpy/Theano中表达c [i,j,k] = a [i,j] * b [i,k]?
- 8. 如何在numpy中有效地实现x [i] [j] = y [i + j]?
- 9. 当A [i,j] = j *(A [i-1,j + 1] -A [i-1,j])时,寻找第i行第一个元素的最有效方法是什么?
- 10. 给定索引i,j(j> = i)如何在子阵列(i,j)上找到A [j]的频率?
- 11. i和j等价于python
- 12. 为什么`double i = 3.3,j = 1.1; int k = i/j; printf(“%d \ n”,k);`得到2?
- 13. 为什么在for循环中“++ i”和“i ++”有什么区别?
- 14. x [i] * x [j]用x [i,j]的Sympy替换
- 15. 是否(!(i%j))表示不是i的模数,j = 0?
- 16. 如果有什么(j!=“”为i中的j):意思?
- 17. C中i--和i-1有什么区别?
- 18. 发现在阵列的(I,J)对总数使得i <j and a[i]>一个[j]的
- 19. m [i] [j] = Double.parseDouble(in.nextLine())是做什么的?
- 20. 为什么tab [i] [j] =“value”段落
- 21. 二维数组,*(pointerArray [i] + j)是什么?
- 22. Java For Loop,为什么J <I?
- 23. Java的为什么对使用I,J
- 24. private(i,j)在这段代码中的作用是什么?如果我从私人(i,j)省略i或j,会有什么变化吗?
- 25. 就原子性而言,i ++和i = i + 1之间的区别
- 26. ++ i和i ++在JavaScript中有什么区别
- 27. 删除G(j,i)条目
- 28. 爪哇:2D阵列的总和,其中所述M [i] [j] =(int)的I/J,
- 29. i == 0和0 == i有区别吗?
- 30. C语言不能打印阵列[i] [j]
这2条线本身是相同的,不管是我还是j的类型。如果您在同一个语句中添加了其他任何内容,则优先顺序可能会改变结果答案。也就是说,我看到一些“不太好”的编译器为它们输出不同的汇编器。去图:) –
检查汇编代码,你可能会发现有趣的细节什么卡尔的回答。 –
查看http://stackoverflow.com/questions/5031604/is-a-b-more-efficient-than-a-a-b-in-c – mizo