Java 为什么会有前缀/后缀++;但是没有前缀/后缀+;=?

Java 为什么会有前缀/后缀++;但是没有前缀/后缀+;=?,java,c++,c,operators,Java,C++,C,Operators,这似乎是一个愚蠢的问题,但为什么在许多语言中都有前缀和后缀版本的++和-运算符,而没有类似的前缀/后缀版本的其他运算符,如+=或-=?例如,如果我可以编写以下代码: myArray[x++] = 137; // Write 137 to array index at x, then increment x 我应该能写一些像这样的东西 myArray[5 =+ x] = 137; // Write 137 to array index at x, then add five to x 当然,这

这似乎是一个愚蠢的问题,但为什么在许多语言中都有前缀和后缀版本的
++
-
运算符,而没有类似的前缀/后缀版本的其他运算符,如
+=
-=
?例如,如果我可以编写以下代码:

myArray[x++] = 137; // Write 137 to array index at x, then increment x
我应该能写一些像这样的东西

myArray[5 =+ x] = 137; // Write 137 to array index at x, then add five to x

当然,这样的运营商并不存在。这有什么原因吗?在C/C++/Java中,这似乎是一种奇怪的不对称现象。

我想这是因为它太神秘了。
有些人认为,即使是++/-也应该避免,因为它们会引起混乱,并导致大多数缓冲区溢出错误。

如果我不得不猜测,通常会等同于:

x+=5

…与:

x=x+5

出于显而易见的原因,写以下内容是荒谬的:

x+5=x


我不知道你还能用
+
操作符模仿
5=+x
的行为。顺便说一句,你好

只要
y
没有副作用:

#define POSTADD(x,y) (((x)+=(y))-(y))

我来做个假设。
++i
/
i++
有很多用例,在许多情况下,特定类型的增量(前/后)会产生不同。我不知道有多少次我看到像
while(buf[I++]){…}
这样的代码。另一方面,
+=
的使用频率要低得多,因为一次将指针移动5个元素几乎没有意义


因此,没有一个足够普遍的应用程序可以将后缀和前缀版本的
+=
区别开来。

因为--and++操作符映射到CPU中的
inc
(rement)和
dec
(rement)指令(除了加和减之外),这些运算符应该映射到指令,因此它们作为单独的运算符存在。

我想有几个原因,我认为权重更大的可能是:

  • 可能没有太多的实际用例(一些语言设计者在早期可能甚至没有想到)
  • 增量前/增量后直接映射到机器操作(至少在几台机器上),因此它们进入了该语言(更新:事实证明,这并不完全正确,即使在计算知识中通常是这样认为的。见下文)
再说一次,虽然前置/后置/递增/递减运算符的想法可能受到机器操作的影响,但看起来它们并不是专门为了利用这些特性而被放入语言中的。以下是丹尼斯·里奇对他们的看法:

汤普森更进一步,发明了++和-,可以递增或递减;它们的前缀或后缀位置决定更改是在记录操作数的值之前还是之后发生。它们不是B的最早版本,而是沿途出现的。人们经常猜测,它们是使用DEC PDP-11提供的自动递增和自动递减地址模式创建的,而C和Unix最初是在DEC PDP-11上流行的。这在历史上是不可能的,因为开发B时没有PDP-11。然而,PDP-7确实有一些“自动递增”的存储单元,其特性是通过它们的间接内存引用使单元递增。这一特性可能向汤普森暗示了这样的操作符;使它们同时成为前缀和后缀的概括是他自己的。事实上,自动增量单元并没有直接用于运算符的实现,而创新的更大动机可能是他观察到的++x的转换比x=x+1的转换小


java和C++有前、后增量和减量运算符,因为C有它们。C之所以有它们,是因为C主要是为PDP-11编写的,PDP-11有

INC
DEC
指令

在当时,优化编译器并不存在,所以如果你想使用单周期增量操作符,要么你为它编写汇编程序,要么你的语言需要一个显式操作符;C、 作为一种可移植的汇编语言,具有显式的递增和递减运算符。另外,
++i
i++
之间的性能差异现在很少重要,但在1972年确实重要


请记住,C已经快40岁了。

因此,基本上,你会问为什么只允许在±1的特殊情况下使用它?就个人而言,我支持
myArray[x++++]137语法。@pst或
myArray[x.plusPlus(10)]=137
@templatetypedef:我觉得这个看起来更好>
myArray[x=+5]=137(添加后)。。。而现有的一个>>
myArray[x+=5]=137(预添加)。。。。想法是,始终保持
x
在左侧!是否应将
x=-1
解析为
x=-1
x=-1
?:)我只使用了PASFIX ++(而且不太经常)——GORAN:这对于C来说是很好的,但对于C++来说,不是那么多(在迭代器上的后缀操作可能相当昂贵)。“有些人认为,即使是++/-应该避免,因为它们会造成混乱,并且对大多数缓冲区溢出错误负责。”这不是
++
--
,而是没有注意缓冲区的长度<如果不注意缓冲区的长度,代码>+=
将无法帮助您避免缓冲区溢出。@Max Lybbert:我认为参数试图说明(;n>0;--n)*dst++=*src++;这不是一种应该使用的风格。有很多东西需要避免,但这并不能说明
++
--
的优点。我的C编程语言副本经过了大量的努力来解释为什么,
(*src++=*dest++)复制空终止