对'a'的多个无序修改?a = a ++

Uni*_*oul -1 c

为什么我不能在Objective-C中执行以下操作?

a = (a < 10) ? (a++) : a;
Run Code Online (Sandbox Code Playgroud)

要么

a = (a++)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

Sul*_*han 5

++a++是后增量。简而言之,请a = a++执行以下操作:

int tmp = a; // get the value of a
a = a + 1 //post-increment a
a = tmp // do the assignment
Run Code Online (Sandbox Code Playgroud)

正如其他人所指出的那样,在C中这实际上是未定义的行为,并且不同的编译器可以对操作进行不同的排序。

尽量避免使用++and --运算符。操作员会引入难以理解的副作用。为什么不简单地写:

if (a < 10) {
   a += 1;
}
Run Code Online (Sandbox Code Playgroud)


Ami*_*wad 5

为了扩展 Sulthan 的答案,您的表达式存在几个问题,至少是简单的赋值(案例 2)。

A. 这样做没有意义。即使a++有一个可以赋值的值(是一个非空表达式),它也会自动将结果赋值给a自己。所以你能期待的最好的相当于

a++;
Run Code Online (Sandbox Code Playgroud)

作业根本无法改善作业。但这不是错误消息。

B. Sulthans 替换声明是一个更好的例子。这更糟糕的:该++运营商具有的价值a(在表达式的开头)和效果,以增加a一些点在未来:增量可以延迟到下一个序列点。

更新操作数的存储值的副作用将发生在前一个和下一个序列点之间。

(ISO/IEC 9899:TC3, 6.5.2.4, 2)

但是赋值运算符=不是一个序列点(附录C)。

以下是5.1.2.3中描述的序列点:

[既不赋值运算符也不)包含在列表中]

因此,该表达可以替换为 Sulthan 所说的:

int tmp = a; // get the value of a
a = a + 1 //post-increment a
a = tmp // do the assignment
Run Code Online (Sandbox Code Playgroud)

结果,a仍然包含旧值。

或者表达式可以替换为以下代码...:

int tmp = a; // get the value of a
a = tmp // assignemnt
a = a + 1 // increment
Run Code Online (Sandbox Code Playgroud)

......结果不同(a递增)。这就是错误消息所说的:没有定义的序列(必须应用操作的顺序。)

您可以使用逗号运算符插入一个序列点,(它的主要用途是什么),...

a++, a=a; // first increment, then assign
Run Code Online (Sandbox Code Playgroud)

……但这显示了你想要做的事情的全部意义。

这与您的第一个示例相同。虽然?是一个序列点……:

以下是5.1.2.3中描述的序列点:

... 以下运算符的第一个操作数的结尾:[...]条件 ? (6.5.15);[…]

... 增量 ( a++) 和赋值 ( a=) 都在?运算符被评估之后,因此再次未排序(“以随机顺序”)。

为了使注释“小心”更具体:不要在表达式中两次使用递增的对象。(除非有明确的序列点)。

int a = 1;
… = a++ * a;
Run Code Online (Sandbox Code Playgroud)

……评价什么?2?1?未定义,因为增量可以在读取a“第二次”后发生。

顺便说一句:Q 与 Objective-C 无关,而是与纯 C 相关。在这一点上,Objective-C 对 C 没有影响。我改变了标签。