В следующем коде я получаю 10 | 1 | 1 в результате. Но в соответствии с правилами приоритета, разве оператор «и» не должен быть оценен первым? (и дать c = 9) Например: d = a || (--b)&&(--c), так как 'and' имеет более высокий приоритет. (или сокращение нарушает правила приоритета?) Заранее спасибо.
#include <stdio.h>
#include <stdlib.h>
int main(){
int a,b,c,d;
a =1;
b = c = 10;
d = a|| --b&&--c;
printf("%d\n",c);
printf("%d\n",a);
printf("%d\n",d);
return 0;
}
Первый дает тот же результат. Второй правильный. Я знаю, что могу написать это так, мой вопрос: почему первый не дает того же результата, что и второй?
Если a равно истинный, в 1-м операторе не оцениваются ни --b, ни --c, а значение всего выражения равно истинный; во 2-м утверждении --b не оценивается, --c оценивается, определяя значение всего выражения.





Приоритет и порядок оценки - две разные вещи. Из документации Логическое ИЛИ (выделено мной):
There is a sequence point after the evaluation of lhs. If the result of lhs compares unequal to zero, then rhs is not evaluated at all (so-called short-circuit evaluation).
В случае exp1 || exp2, exp1 всегда оценивается первым, так как после него идет точка следования, и если exp1 не равно нулю, то exp2 не оценивается.
Тогда компилятор не может сначала оценить rhs, который содержит оператор «и» из-за этой точки последовательности? Итак, если это правильно, то порядок оценки может повлиять на приоритет, как это происходит в этом примере? (или приоритет остается прежним, но результат вычисления отличается от приоритета)
@Crazy_39365: || и && заставляют оценивать слева направо (в отличие от большинства операторов в C). Приоритет Только влияет на то, как операнды группируются с операторами.
Приоритет определяет только то, какие операнды сгруппированы с какими операторами, но не определяет порядок, в котором вычисляются выражения.
В вашем примере это означает, что выражение анализируется как
a || (––b && ––c)
И ||, и && принудительно оценивают слева направо1. Оба вводят точку последовательности (IOW, левый операнд будет оцениваться, и все побочные эффекты будут применены до того, как будет оценен правый операнд).
Оба оператора короткое замыкание - если левый операнд || оценивается как ненулевой, то результат выражения равен 1 (истина) независимо от значения правого операнда, поэтому правый операнд вообще не оценивается. Если левый операнд && равен 0, то результат выражения равен 0 (ложь) независимо от значения правого операнда, поэтому правый операнд вообще не оценивается.
В вашем выражении a оценивается первым. Он имеет ненулевое значение (1), поэтому ––b && ––c не оценивается.
?: and comma operators. All other operators (arithmetic, equality, subscript, etc.) do not force a particular order of evaluation.
Если вы пишете выражение самостоятельно, используйте круглые скобки:
d = (a || (--b && --c));илиd = ((a || --b) && --c);и/или временные переменные:tmp = --b && --c; d = a || tmp;