Перейти к содержанию

Приоритет операции

Эта статья находится на начальном уровне проработки, в одной из её версий выборочно используется текст из источника, распространяемого под свободной лицензией
Материал из энциклопедии Руниверсалис

Приоритет, ранг или старшинство операции или оператора — формальное свойство оператора/операции, влияющее на очередность его выполнения в выражении с несколькими различными операторами при отсутствии явного (с помощью скобок) указания на порядок их вычисления. Например, операцию умножения обычно наделяют бо́льшим приоритетом, чем операцию сложения, поэтому в выражении [math]\displaystyle{ x+y\cdot z }[/math] будет получено сначала произведение [math]\displaystyle{ y }[/math] и [math]\displaystyle{ z }[/math], а потом уже сумма.

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

В формальных системах используется два способа задания приоритета любого оператора. Первый из них — распределение всех операторов по иерархии приоритетов. Этот способ всегда используется для задания приоритетов по умолчанию и фиксируется в описании языка в виде соглашения, что таким-то операторам присваивается такие-то приоритеты. Никакого отражения в синтаксисе языка он не получает, то есть при нём не используется никаких явных средств (= тех/иных символов) для указания приоритета операции.

Второй способ дает возможность менять приоритеты по умолчанию, указывая их в явном виде с помощью символов парных скобок. При этом глубина вложенности прямо пропорциональна величине приоритета, то есть более внутренние скобки указывают на больший приоритет, чем внешние, обрамляющие их. В предыдущем примере с суммой и произведением порядок вычисления можно поменять, используя скобки, записав всё выражение так: [math]\displaystyle{ ((x+y)\cdot z) }[/math] или же так: [math]\displaystyle{ (x+y)\cdot z }[/math].

Практика ранжирования операций

В языке C++

Приоритет операций — очерёдность выполнения операций в выражении, при условии, что в выражении нет явного указания порядка следования выполнения операций (с помощью круглых скобок).

Если операции имеют одинаковый приоритет, то очерёдность выполнения таких операций определяется согласно свойству ассоциативности.

Ассоциативность — направление выполнения операций в случае, если операции имеют одинаковый приоритет:

Приоритет Операция Ассоциативность Описание
1 :: слева направо унарная операция разрешения области действия
[ ] операция индексирования
() круглые скобки
. обращение к члену структуры или класса
-> обращение к члену структуры или класса через указатель
2 ++ слева направо постфиксный инкремент
постфиксный декремент
3 ++ справа налево префиксный инкремент
префиксный декремент
4 * слева направо умножение
/ деление
% остаток от деления
5 + слева направо сложение
вычитание
6 >> слева направо сдвиг вправо
<< сдвиг влево
7 < слева направо меньше
<= меньше либо равно
> больше
>= больше либо равно
8 == слева направо равно
!= не равно
9 && слева направо логическое И
10 || слева направо логическое ИЛИ
11 ?: справа налево условная операция (тернарная операция)
12 = справа налево присваивание
*= умножение с присваиванием
/= деление с присваиванием
%= остаток от деления с присваиванием
+= сложение с присваиванием
-= вычитание с присваиванием
13 , слева направо запятая

В сомнительных случаях следует использовать скобки. В некоторых случаях приоритет операций может давать неявные эффекты. Рассмотрим пример:

int n = 5;
cout << n += 3;

Несмотря на очевидность кода для человека, компилятор выдаст ошибку: в выражении в строке 2 первым выполнится оператор побитового сдвига (<<) так как его приоритет равен 6 и он выше чем приоритет оператора «сложение с присваиванием» (+=) 12. В итоге значение переменной n будет передано в поток cout, а операция += не выполнится.