为什么我不能在Objective-C中执行以下操作?
a = (a < 10) ? (a++) : a;
Run Code Online (Sandbox Code Playgroud)
要么
a = (a++)
Run Code Online (Sandbox Code Playgroud)
在++在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)
为了扩展 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 没有影响。我改变了标签。