Таблица 1. Приоритеты и очередность вычислений операторов
| Операторы | Выполняются | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| () | [] | -> | . | слева направо | |||||||
| ! | ~ | ++ | -- | + | - | * | & | (type) | sizeof | справа налево | |
| * | / | % | слева направо | ||||||||
| + | - | слева направо | |||||||||
| << | >> | слева направо | |||||||||
| < | <= | > | >= | слева направо | |||||||
| == | != | слева направо | |||||||||
| & | слева направо | ||||||||||
| ^ | слева направо | ||||||||||
| | | слева направо | ||||||||||
| && | слева направо | ||||||||||
| || | слева направо | ||||||||||
| ?: | справа налево | ||||||||||
| = | += | -= | *= | /= | %= | &= | ^= | |= | <<= | >>= | справа налево |
| , | слева направо | ||||||||||
Примечание. Унарные операторы +, -, * и & имеют более высокий приоритет, чем те же бинарные операторы.
Приоритеты побитовых операторов &, ^ и | ниже, чем приоритет == и !=, из-за чего в побитовых проверках, таких как
if ((х & MASK) == 0) ...
чтобы получить правильный результат, необходимо использовать скобки.
чтобы получить правильный результат, необходимо использовать скобки.
В языке Си очередность вычисления операндов оператора не фиксируется. В инструкции
х = f() + g();
f может быть вычислена раньше g или наоборот. Из этого следует, что если одна из функций изменяет значение переменной, от которой зависит другая функция, то помещаемый в x результат может зависеть от очередности вычислений. Чтобы обеспечить нужную последовательность вычислений, промежуточные результаты можно запоминать во временных переменных.
printf("%d %d\n", ++n, power(2, n)); /* НЕВЕРНО */
может давать несовпадающие результаты. Результат вызова функции зависит от того, когда компилятор сгенерирует команды увеличения n — до или после обращения к power. Чтобы обезопасить себя от возможного побочного эффекта, достаточно написать
++n;
printf("%d %d\n", n, power(2, n));
printf("%d %d\n", n, power(2, n));
Обращения к функциям, вложенные присвоения, инкрементные и декрементные операторы дают "побочный эффект", проявляющийся в том, что при вычислении выражения значения некоторых переменных изменяются. В любом выражении с побочным эффектом может быть скрыта трудно просматриваемая зависимость результата выражения от очередности изменения значений переменных, входящих в выражение. В такой, например, типично неприятной ситуации
a[i] = i++;
возникает вопрос: массив a индексируется старым или измененным значением i?
Авторы книги рекомендуют не писать программы, зависящие от очередности вычислений, так как компиляторы могут по-разному их генерировать в зависимости от архитектуры машины.
Комментариев нет:
Отправить комментарий