Как на самом деле работает приоритет оператора в этой программе?

#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++); это правильный операнд, а остальное должно быть совершенно ясно.:)

Другие вопросы по тегам