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

时间:2019-06-14 04:07:57

标签: 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]);
}

此输出为

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;

无论从左到右还是从右到左看表情,关联属性也使人困惑。

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。