我很困惑下面的代码如何执行该表达式。
#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]);
}
此输出为
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;
无论从左到右还是从右到左看表情,关联属性也使人困惑。
答案 0 :(得分:5)
您的代码具有未定义的行为。
a[0] = a[0] - (a[0] = a[1]);
子表达式(a[0] = a[1])
本身是有效的。它将a[1]
的值分配给a[0]
,并产生分配的值。
问题在于a[0]
在单个表达式中被修改了两次,并且没有顺序,这意味着该语言没有告诉我们先发生哪个。 (在C90 / C99术语中,两个修饰没有用序列点隔开。)
一个更简单的例子:
x = 2 + (x = 1);
这里x
被修改了两次。该语言不仅说这两种修改可以以任何顺序进行,还可以。它说行为是不确定的。换句话说,该语言没有说明会发生什么。它可能崩溃,可能给您带来一些垃圾结果,或者最糟糕的是,它可能会做您期望的事情。 (这是最坏的情况,因为这意味着您仍然有一个严重的错误,很难对其进行检测和诊断。)
最底线:无论打算执行什么代码行,肯定都有一种更清晰,更明确的方法。您所质疑的代码不要太苛刻,甚至也可能不是C。