为什么人们会写--i?

4

可能是重复问题:
C++中的增量 - 何时使用x++或++x?

我经常在for循环等地方看到i++这样的代码。但当人们用--代替++时,一些人会倾向于写成--i而不是i--

在我上次查看时,它们都可以工作(至少在JavaScript中)。请问在其他C系列语言中是否也是这样,并且如果是,为什么有些人更喜欢--i而不是i--


2
这不是语言无关的,对于C和C++有不同的答案。 - Bo Persson
6个回答

12

++ii++快。为什么?看一下简单的解释。

i++

i++会将i的值增加1,但返回未增加前的值。

  • temp = i
  • i被增加
  • 返回temp

示例:

i = 1;
j = i++;
(i is 2, j is 1)

++i

++i会将i的值加1,然后返回递增后的值。

示例:

i = 1;
j = ++i;
(i is 2, j is 2)

这与 --ii-- 相似。


1
但是为什么有人会使用 i++ 而不是 --i 呢?这就是问题所在。 - Bo Persson
编译器可以轻松检测变量 temp 是否被使用。因此,我怀疑这段代码是否更快。 - Emanuele Paolini
1
@EmanuelePaolini:是的。有一个C语言相关的问题。简而言之,任何稍微新一点的编译器都会优化掉它们之间的差异,即使你使用了结果值。在Java中,如果你不使用结果,字节码是相同的。如果你使用了结果,那么只是操作码的顺序问题(对于本地整数,我没有深入研究),iinc / iload_1iload_1 / iinc。当然,JIT可能会介入。但是,由于我更喜欢前缀...;-) - T.J. Crowder

5

历史上,增量/减量运算符是由堆栈管理所激发的。当您将一个元素推入堆栈时:

*(stackptr++) = value

当你弹出:

value = *(--stackptr)

(这些被转换为单个ASM指令)

因此,我们习惯于后增和前减。

在直接和反向顺序填充中,您可以看到另一个惯用的例子:

for (p=begin;p!=end;) 
    *(p++) = 42;

for (p=end;p!=begin;) 
    *(--p) = 42;

5

我不认为使用前缀 (++i) 或后缀 (i++) 取决于是增量还是减量。

至于为什么,我喜欢在可能的情况下使用前缀,因为我的母语是英语,它通常具有动词-宾语结构(“吃晚饭”,“开车”),所以“增加i”或“减少i”对我来说比“i减少”更自然。当然,如果我需要在表达式中使用结果并且需要增量之前的值 (而不是增量后的值),我会愉快地使用后缀。


uh前缀至少和后缀一样高效,甚至可能更高效。如此解释:https://dev59.com/l3I-5IYBdhLWcg3whYsr#1813008 - paul23

4
这基本上是一种偏好,只有在对比原始类型更为复杂的类型进行前置或后置增量运算时才会发挥作用。

前置增量("++i")将在增加i的值之后返回该值,并且后置增量 ("i++")将在增加前返回该值。因此,如果i是一种复杂类型,它已经重载了前置和后置增量运算符,则前置增量运算符可以直接返回该对象,而后置增量运算符则必须返回该对象的副本,如果该对象很大,则效率可能会较低。在大多数情况下(例如循环增量等),这个值都被忽略了,所以这只是一个偏好问题,大部分时间不会有问题。

2
在C和C++中,++--运算符都有前缀形式:++i--i,以及后缀形式:i++i--。前者意味着先计算再使用,后者意味着先使用再计算。只有当其中一种形式作为表达式的一部分时,这种差异才是相关的。否则,这只是偏好或风格(或缺乏风格)的问题。
例如,在int i = 0; int n = ++i;中,i首先被增加,然后其值,现在是1,被赋给n。在n = i++中,i的值仍然是1,被赋给n,然后被增加,现在i == 2
当用作语句时,即:i++; ++i;两种形式是等价的。

你帖子中的最后一句话并不完全正确。对于基本类型,如果结果没有被使用,编译器可能通过将i++替换为++i来进行优化。如果它不执行此优化,则可能会在性能上产生(非常小的)差异。然而,对于具有重载operator ++的用户定义类型,这种优化是不允许的(因为编译器无法保证您已经正确实现了两个操作符之间的预期关系)。这意味着,在C++中选择哪种形式实际上会影响结果。 - Agentlien

1
差别在于前置递增或后置递增(递减同理)。
引用维基百科文章中的内容,该文章是谷歌搜索“c decrement”排名第二的结果:
int  x;
int  y;

// Increment operators
x = 1;
y = ++x;    // x is now 2, y is also 2
y = x++;    // x is now 3, y is 2

// Decrement operators
x = 3;
y = x--;    // x is now 2, y is 3
y = --x;    // x is now 1, y is also 1

因此,这不仅仅是偏好的问题,而是结果差异的问题。

当然可以,但问题是为什么要使用前缀或后缀。 - mattjgalloway

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接