Как на самом деле работает приоритет оператора в этой программе?
#include<stdio.h>
int main()
{
int i=-1, j=-1, k=-1, l=2, m;
m = (i++ && j++ && k++) || (l++);
printf("%d %d %d %d %d", i, j, k, l, m);
}
У меня возникли путаницы по поводу того, как работает приоритет операторов при оценке логического выражения в данной программе.
Переменная m
будет назначен 0
или же 1
в зависимости от значения логического выражения, которое следует за ним.
Первая скобка будет оценена, и общий результат двух операций И будет истинным или 1
, Но, поскольку используется логическое ИЛИ короткого замыкания, вторая скобка не оценивается.
Итак, мой вопрос: если скобки имеют более высокий приоритет, чем все остальные операторы в этом выражении, почему сначала не вычисляются обе скобки, а затем выполняется операция ИЛИ? То есть почему выход 0 0 0 2 1
и не 0 0 0 3 1
?
РЕДАКТИРОВАТЬ: То, что я спросил, несколько отличается от этого (предлагается дубликат), как я подчеркиваю в скобках, включающих второй операнд оператора OR.
2 ответа
Приоритет оператора (и ассоциативность) определяет только способ анализа выражения. Распространенная ошибка - путать его с порядком вычисления операндов, что совсем другое. Приоритет оператора в этом примере не имеет значения.
Для большинства операторов в C порядок вычисления операндов не указан. Ты написал true | l++
затем l++
был бы казнен. "Оценка короткого замыкания" является причиной, почему этого не происходит в вашем коде. && ||
Операторы - это особый случай, поскольку они явно определяют порядок вычисления. Правильный операнд ||
гарантированно не будет оцениваться в случае, если левый операнд оценивается как ненулевой.
Приоритет оператора вступает в силу, когда возникает неопределенность.
В этом случае спецификация вполне понятна.
||
оператор должен уступить1
если один из его операндов сравнивать неравно0
; в противном случае это дает0
, Результат имеет типint
,
и (выделение мое)
В отличие от побитового
|
оператор,||
оператор гарантирует оценку слева направо; если вычисляется второй операнд, между оценками первого и второго операндов существует точка последовательности. Если первый операнд сравнивается неравно0
второй операнд не оценивается.
В твоем случае,
(i++ && j++ && k++) || (l++);
(i++ && j++ && k++)
это левый операнд и (l++);
это правильный операнд, а остальное должно быть совершенно ясно.:)