Почему не ++ я ||++ j && ++ k дает ожидаемое значение - PullRequest
6 голосов
/ 04 апреля 2019

Я хочу знать, почему значение k в приведенном ниже коде равно 1.

Я думаю ++i || ++j && ++k выполняется по порядку:

((++i || ++j) && ++k)

Итак, в первом фрагменте (++i || ++j), ++i имеет значение true, поэтому ++j не оценивается, поэтому i=2, j=1. Затем во втором фрагменте (true && ++k), то есть ++k, и затем k=2.

#include <stdio.h>

int main(void)
{
    int i, j, k;

    i = 1; j = 1; k = 1;
    printf("%d ", ++i || ++j && ++k);
    printf("%d %d %d\n", i, j, k);
    return 0;
}

Но

printf("%d %d %d\n", i, j, k);

показывает

2 1 1

Я не знаю, что ошибалось или что я неправильно понял.

Ответы [ 2 ]

17 голосов
/ 04 апреля 2019

Логический оператор И && имеет более высокий приоритет, чем логический оператор ИЛИ ||.Таким образом, выражение фактически анализируется как:

++i || (++j && ++k)

++i оценивается как true, поэтому вся правая часть ||, то есть ++j && ++k, не оценивается.В результате этого не увеличивается ни j, ни k.

Может быть трудно запомнить все правила приоритета, как для себя, так и для других, кто читает ваш код.Поэтому, если сомневаетесь, используйте скобки, чтобы уточнить свои намерения.

4 голосов
/ 04 апреля 2019

Запуск с предупреждениями компилятора или хорошим редактором, таким как Atom.io , выявляет проблему.

cc -Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c99 -pedantic -g `pkg-config --cflags glib-2.0`   -c -o test.o test.c
test.c:8:30: warning: '&&' within '||' [-Wlogical-op-parentheses]
    printf("%d ", ++i || ++j && ++k);
                      ~~ ~~~~^~~~~~
test.c:8:30: note: place parentheses around the '&&' expression to silence this warning
    printf("%d ", ++i || ++j && ++k);
                             ^
                         (         )
1 warning generated.

Это проблема приоритета.Операторы в выражении оцениваются не слева направо, а в порядке приоритета.++i || ++j && ++k оценивается как ++i || (++j && ++k), поскольку && имеет более высокий приоритет, чем ||.

Чтобы избежать этих проблем, включите предупреждения компилятора и сделайте это привычкойставьте скобки вокруг всего, что может быть неоднозначным.

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