Пространства имён
Варианты
Действия

Приоритет операторов C++

Материал из cppreference.com
< cpp‎ | language
 
 
Язык С++
Общие темы
Управление потоком
Операторы условного выполнения
Операторы итерации (циклы)
Операторы перехода
Функции
Объявление функции
Выражение лямбда-функции
Спецификатор inline
Спецификации динамических исключений (до C++17*)
Спецификатор noexcept (C++11)
Исключения
Пространства имён
Типы
Спецификаторы
decltype (C++11)
auto (C++11)
alignas (C++11)
Спецификаторы длительности хранения
Инициализация
Выражения
Операторы
Приоритет оператора
Альтернативные представления
Литералы
Логические - Целочисленные - С плавающей запятой
Символьные - Строковые - nullptr (C++11)
Определяемые пользователем (C++11)
Утилиты
Атрибуты (C++11)
Types
Объявление typedef
Объявление псевдонима типа (C++11)
Casts
Неявные преобразования - Явные преобразования
static_cast - dynamic_cast
const_cast - reinterpret_cast
Выделение памяти
Классы
Свойства функции класса
Специальные функции-элементы
Шаблоны
Разное
 
Выражения
Общие
Категории значений (lvalue, rvalue, xvalue)
Порядок оценки (точки последовательности)
Константные выражения
Потенциально оцениваемые выражения
Первичные выражения
Лямбда-выражения(C++11)
Литералы
Целочисленные литералы
Литералы с плавающей запятой
Логические литералы
Символьные литералы, включая управляющие последовательности
Строковые литералы
Литерал нулевого указателя(C++11)
Пользовательский литерал(C++11)
Операторы
a=b, a+=b, a-=b, a*=b, a/=b, a%=b, a&=b, a|=b, a^=b, a<<=b, a>>=b
++a, --a, a++, a--
+a, -a, a+b, a-b, a*b, a/b, a%b, ~a, a&b, a|b, a^b, a<<b, a>>b
a||b, a&&b, !a
a==b, a!=b, a<b, a>b, a<=b, a>=b, a<=>b (начиная с C++20)
a[b], *a, &a, a->b, a.b, a->*b, a.*b
a(...), a,b, a?b:c
выражение new
выражение delete
выражение throw
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
Выражения свёртки(C++17)
Альтернативные представления операторов
Приоритет и ассоциативность
Перегрузка операторов
Сравнение по умолчанию(C++20)
Преобразования
Неявные преобразования
Обычные арифметические преобразования
const_cast
static_cast
reinterpret_cast
dynamic_cast
Явные преобразования: (T)a, T(a), auto(a), auto{a} (начиная с C++23)
Пользовательское преобразование
 

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

ПриоритетОператорОписаниеАссоциативность
1::Разрешение области видимостиСлева направо →
2a++   a--Суффиксный/постфиксный инкремент и декремент
тип()   тип{}Функциональный оператор приведения типов
a()Вызов функции
a[]Индексация
.   ->Доступ к элементу
3++a   --aПрефиксный инкремент и декрементСправа налево ←
+a   -aУнарные плюс и минус
!   ~Логическое НЕ и побитовое НЕ
(тип)Приведение типов в стиле C
*aКосвенное обращение (разыменование)
&aВзятие адреса
sizeofРазмер в байтах[примечание 1]
co_awaitВыражение await (C++20)
new   new[]Динамическое распределение памяти
delete   delete[]Динамическое освобождение памяти
4.*   ->*Указатель на элементСлева направо →
5a*b   a/b   a%bУмножение, деление и остаток от деления
6a+b   a-bСложение и вычитание
7<<   >>Побитовый сдвиг влево и сдвиг вправо
8<=>Оператор трёхстороннего сравнения (начиная с C++20)
9<   <=   >   >=Для операторов отношения < и ≤ и > и ≥ соответственно
10==   !=Операторы равенства = и ≠ соответственно
11a&bПобитовое И
12^Побитовый XOR (исключающее или)
13|Побитовое ИЛИ (включающее или)
14&&Логическое И
15||Логическое ИЛИ
16a?b:cТернарный условный оператор[примечание 2]Справа налево ←
throwОператор throw
co_yieldВыражение yield (C++20)
=Прямое присваивание (предоставляется по умолчанию для классов C++)
+=   -=Составное присваивание с сложением и вычитанием
*=   /=   %=Составное присваивание с умножением, делением и остатком от деления
<<=   >>=Составное присваивание с побитовым сдвигом влево и сдвигом вправо
&=   ^=   |=Составное присваивание с побитовым И, XOR и ИЛИ
17,ЗапятаяСлева направо →
  1. Операнд sizeof не может быть приведением типа в стиле C: выражение sizeof(int)*p однозначно интерпретируется как (sizeof(int))*p, но не sizeof((int)*p).
  2. Выражение в середине условного оператора (между ? и :) анализируется, как если бы оно было заключено в скобки: его приоритет относительно ?: игнорируется.

При синтаксическом анализе выражения оператор, указанный в некоторой строке приведённой выше таблицы, будет более тесно связан со своими аргументами (как в случае применения скобок), чем любой оператор из строк, расположенных ниже, с более низким приоритетом. Например, выражения std::cout<<a&b и *p++ будут разобраны как (std::cout<<a)&b и *(p++), а не как std::cout<<(a&b) и (*p)++.

Операторы с одинаковым приоритетом связываются со своими аргументами в направлении их ассоциативности. Например, выражение a = b = c будет разобрано как a = (b = c), а не (a = b) = c, так как ассоциативность присваивания справа налево, но a + b - c будет разобрано как (a + b) - c, а не a + (b - c), так как ассоциативность сложения и вычитания слева направо.

Спецификация ассоциативности избыточна для унарных операторов и показана только для полноты: унарные префиксные операторы всегда связываются справа налево (delete ++*p равно delete(++(*p))), а унарные постфиксные операторы всегда связываются слева направо (a[1][2]++ равно ((a[1])[2])++). Обратите внимание, что ассоциативность имеет значение для операторов доступа к элементам, даже если они сгруппированы с унарными постфиксными операторами: a.b++ будет разобрано как (a.b)++, а не a.(b++).

Приоритет операторов не зависит от перегрузки операторов. Например, std::cout << a ? b : c; будет разобрано как (std::cout << a) ? b : c;, так как приоритет арифметического сдвига влево выше, чем у условного оператора.

[править] Примечания

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

Сам стандарт не определяет порядок приоритетов. Они выводятся из грамматики.

const_cast, static_cast, dynamic_cast, reinterpret_cast, typeid, sizeof..., noexcept и alignof не включены в таблицу, поскольку они никогда не бывают двусмысленными.

У некоторых операторов есть альтернативное написание (например, and для &&, or для ||, not для ! и т.д.).

В языке C тернарный условный оператор имеет более высокий приоритет, чем операторы присваивания. Следовательно, выражение e = a < d ? a++ : a = d, которое разбирается в C++ как e = ((a < d) ? (a++) : (a = d)), не будет скомпилировано в C из-за грамматических или семантических ограничений. Подробности смотрите на соответствующей странице C.

[править] Смотрите также

Общие операторы
присваиваниеинкремент
декремент
арифметическиелогическиесравнениядоступ к элементудругие

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[...]
*a
&a
a->b
a.b
a->*b
a.*b

вызов функции
a(...)
запятая
a, b
условный
a ? b : c
Специальные операторы

static_cast приводит один тип к другому совместимому типу
dynamic_cast приводит к типу в иерархиях наследования
const_cast добавляет или удаляет cv квалификаторы
reinterpret_cast приводит тип к несовместимому типу
приведение в стиле C приводит один тип к другому с помощью сочетания static_cast, const_cast и reinterpret_cast
new создаёт объекты с динамическим классом памяти
delete разрушает объекты, ранее созданные выражением new, и освобождает полученную область памяти
sizeof запрашивает размер типа
sizeof... запрашивает размер пакета параметров (начиная с C++11)
typeid запрашивает сведения о типе
noexcept проверяет, может ли выражение вызвать исключение (начиная с C++11)
alignof запрашивает требования к выравниванию типа (начиная с C++11)

Документация C по Приоритет операторов C