я поражен потоком казни, кто-нибудь может мне помочь - PullRequest
0 голосов
/ 14 июня 2019

Я запутался, как выполняется выражение для следующего кода.

#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 Ответ

5 голосов
/ 14 июня 2019

Ваш код имеет неопределенное поведение .

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...