Путаница с ассоциативностью оператора присваивания в C - PullRequest
3 голосов
/ 05 августа 2011

Как мы все знаем, ассоциативность оператора присваивания справа налево, но в данном коде вывод должен быть равен нулю, если мы идем справа налево, но вывод равен 1.

 main()
 {
 int a=3,b=2;
 a=a==b==0;
 printf("%d",a);
 }

Как выходной результат будет равен 1, если мы по праву перейдем к letf ??

Если мы идем справа налево, тогда (b == 0) сначала нужно оценить и дать результат 0, а затем выражение (a == 0) оценивается и дать 0 и, наконец, значение a будет равно 0.

Ответы [ 3 ]

7 голосов
/ 05 августа 2011

Назначение выполняется RTL, но равенство (==) - нет.

На самом деле это утверждение:

a = ((a == b) == 0)

Правая часть задания оценивается слева направо. Пошагово, вот что происходит:

  1. a == b является 0
  2. 0 == 0 является 1
  3. 1 назначен на a
4 голосов
/ 08 июля 2013

Заметьте, это сформулировано так, как оно было объединено с этого вопроса .ОП спросил, почему a==b==c эквивалентно a==b && b==c в Задаче C (которая является строгим надмножеством C).Я попросил, чтобы этот ответ был перенесен, так как он ссылается на спецификацию, где другие ответы здесь не нужны.


Нет, это не так, это похоже на (a==b) == c.

Давайте посмотрим напростой контрпример к вашему правилу:

(0 == 0 == 0);// evaluates to 0

Однако

(0 == 0) && (0 == 0) // evaluates to 1

Логика проблематична, поскольку:

(0 == 0 == 0) считывается как ((0 == 0) == 0), что аналогичнона 1 == 0, что неверно (0).


Для амбициозного студента

Небольшое погружение в то, как это оценивается.Языки программирования включают грамматику , которая определяет, как вы читаете утверждение на языке.У Siance Objective-C нет фактической спецификации. Я буду использовать спецификацию C, поскольку target-c является строгим расширенным набором c.

Стандарт гласит, что equality expression (6.5.9) оценивается какследующее:

Выражение равенства:

выражение отношения

выражение равенства == выражение отношения

Выражение равенства! = выражение отношения

Наш случай - второй, поскольку в a == b == c читается как equality_expression == relational_expression, где первое выражение равенства - a == b.

(Теперь фактический номер результата следует довольно далеко от буквального числа: равенство-> реляционный-> сдвиг-> аддитивный-> мультипликативный-> приведение-> унарный-> постфикс-> основной->постоянный, но не в этом суть)

Таким образом, спецификация четко заявляет , что a==b==c делает не оценивается так же, как a==b && b==c

Стоит отметить, что некоторые языки поддерживают выражения в форме a<b<c, однако C не является одним из таких языков.

4 голосов
/ 05 августа 2011

Ваш код эквивалентен:

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