我对下面的代码如何执行表达式感到困惑。
#include<stdio.h>
int main()
{
int a[10];
a[0] = 1;
a[1] = 2;
printf("%d %d",a[0],a[1]);
a[0] = a[0] - (a[0] = a[1]); // not able to understand its flow of execution
printf("\n%d %d",a[0],a[1]);
}
Run Code Online (Sandbox Code Playgroud)
输出是
1 2
-1 2
我的疑问是括号内的赋值运算符在哪里执行并更改a [0]元素,并在表达式中使用,例如
索引:0 1
元素:1 2
在表达式中:2 2 //当(a [0] = a [1])
a [0] = a [0]-(a [0]-a [1]);
a [0] = 1-(2);
a [0] = -1;
(要么)
索引:0 1
元素:1 2
在表达式中:1 2 //当(a [0] = a [1])
a [0] = a [0]-(a [0]-a [1]);
a [0] = 1-(2);
a [0] = -1;
无论从左到右还是从右到左看表达,联想属性也很困惑。
您的代码具有未定义的行为。
a[0] = a[0] - (a[0] = a[1]);
Run Code Online (Sandbox Code Playgroud)
就其本身而言,子表达式(a[0] = a[1])是有效的。它将的值分配a[1]给a[0],并产生已分配的值。
问题在于,在单个表达式中a[0]被修改了两次,并且两个修改都没有顺序,这意味着该语言不会告诉我们哪个首先发生。(用C90 / C99而言,两个修饰符之间没有分隔点。)
一个更简单的例子:
x = 2 + (x = 1);
Run Code Online (Sandbox Code Playgroud)
这里x被修改了两次。该语言不仅说这两种修改可以以任何顺序进行,还可以。它说行为是不确定的。换句话说,该语言没有说明会发生什么。它可能崩溃,可能给您带来一些垃圾结果,或者最糟糕的是,它可能会做您期望的事情。(这是最坏的情况,因为这意味着您仍然有一个严重的错误,很难对其进行检测和诊断。)
底线:无论该行代码打算做什么,都肯定有一种更清晰,更明确的方法。您所询问的代码不要太苛刻,甚至可能不是C。