Приоритеты

Приоритеты операций задают последовательность вычислений в сложном выражении. Например, какое значение получит ival?

Если вычислять операции слева направо, получится 20. Среди других возможных результатов будут 9, 14 и 36. Правильный ответ: 14.

В С++ умножение и деление имеют более высокий приоритет, чем сложение, поэтому они будут вычислены раньше. Их собственные приоритеты равны, поэтому умножение и деление будут вычисляться слева направо. Таким образом, порядок вычисления данного выражения таков:

Следующая конструкция ведет себя не так, как можно было бы ожидать. Приоритет операции присваивания меньше, чем операции сравнения:

Программист хотел присвоить переменной ch значение, а затем проверить, равно ли оно символу новой строки. Однако на самом деле выражение сначала сравнивает значение, полученное от nextChar(), с ‘\n’, и результат – true или false – присваивает переменной ch.
Приоритеты операций можно изменить с помощью скобок. Выражения в скобках вычисляются в первую очередь.

Например:

Вот как с помощью скобок исправить поведение предыдущего примера:

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

Сначала kval получает значение lval, затем jval – значение результата этого присваивания, и в конце концов ival получает значение jval.
Арифметические операции, наоборот, левоассоциативны. Следовательно, в выражении:

сначала складываются ival и jval, потом к результату прибавляется kval, а затем и lval.

В таблице далее приведен полный список операторов С++ в порядке уменьшения их приоритета. Операторы внутри одной секции таблицы имеют равные приоритеты. Все операторы некоторой секции имеют более высокий приоритет, чем операторы из секций, следующих за ней. Так, операции умножения и деления имеют одинаковый приоритет, и он выше приоритета любой из операций сравнения.

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

Оператор Значение Использование
:: Глобальная область видимости ::name
:: Область видимости класса class::name
:: Область видимости пространства имен namespace::name
. Доступ к члену object.member
-> Доступ к члену по указателю pointer->member
[] Взятие индекса variable[expr]
() Вызов функции name(expr_list)
() Построение значения type(expr_list)
++ постфиксный инкремент lvalue++
постфиксный декремент lvalue—
typeid идентификатор типа typeid(type)
typeid идентификатор типа выражения typeid(expr)
преобразование типа const_cast<type>(expr)
преобразование типа dynamic_cast<type>(expr)
reinterpret_cast приведение типа reinterpret_cast<type> (expr)
static_cast приведение типа static_cast<type>(expr)
sizeof размер объекта sizeof expr
sizeof размер типа sizeof( type)
++ префиксный инкремент ++lvalue
префиксный декремент —lvalue
~ побитовое НЕ ~expr
! логическое НЕ !expr
унарный минус -expr
+ унарный плюс +expr
* разыменование *expr
& адрес &expr
() приведение типа (type)expr
new выделение памяти new type
new выделение памяти и инициализация new type(exprlist)
new Выделение памяти под массив все формы
delete освобождение памяти все формы
delete освобождение памяти из-под массива все формы
->* доступ к члену классу по указателю pointer-> *pointer_to_member
.* доступ к члену класса по указателю object.*pointer_to_member
* Умножение expr * expr
/ Деление expr / expr
% деление по модулю expr % expr
+ сложение expr + expr
вычитание expr — expr
<< сдвиг влево expr << expr
>> сдвиг вправо expr >> expr
< меньше expr < expr
<= меньше или равно expr <= expr
> больше expr > expr
>= больше или равно expr >= expr
== равно expr == expr
!= не равно expr != expr
& побитовое И expr & expr
^ побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ expr ^ expr
| побитовое ИЛИ expr | expr
&& логическое И expr && expr
|| логическое ИЛИ expr || expr
?: условный оператор expr ? expr * expr
= присваивание l-значение = expr
=, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^= составное присваивание l-значение += expr и т.д.
throw возбуждение исключения throw expr
, запятая expr, expr

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

14 − три =