我对执行流程感到震惊,谁能帮我

sel*_*i s -5 c

我对下面的代码如何执行表达式感到困惑。

#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;

无论从左到右还是从右到左看表达,联想属性也很困惑。

Kei*_*son 5

您的代码具有未定义的行为

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。