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

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

Материал из cppreference.com
< cpp‎ | language
 
 
Язык С++
Общие темы
Управление потоком
Операторы условного выполнения
if
Операторы итерации (циклы)
Операторы перехода
Функции
Объявление функции
Выражение лямбда-функции
Спецификатор 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
Выделение памяти
Классы
Свойства функции класса
explicit (C++11)
static
Специальные функции-элементы
Шаблоны
Разное
 
Выражения
Общие
Категории значений (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 :: Разрешение области видимости Слева направо →
2 a++   a-- Суффиксный/постфиксный инкремент и декремент
тип()   тип{} Функциональный оператор приведения типов
a() Вызов функции
a[] Индексация
.   -> Доступ к элементу
3 ++a   --a Префиксный инкремент и декремент Справа налево ←
+a   -a Унарные плюс и минус
!   ~ Логическое НЕ и побитовое НЕ
(тип) Приведение типов в стиле C
*a Косвенное обращение (разыменование)
&a Взятие адреса
sizeof Размер в байтах[примечание 1]
co_await Выражение await (C++20)
new   new[] Динамическое распределение памяти
delete   delete[] Динамическое освобождение памяти
4 .*   ->* Указатель на элемент Слева направо →
5 a*b   a/b   a%b Умножение, деление и остаток от деления
6 a+b   a-b Сложение и вычитание
7 <<   >> Побитовый сдвиг влево и сдвиг вправо
8 <=> Оператор трёхстороннего сравнения (начиная с C++20)
9 <   <=   >   >= Для операторов отношения < и ≤ и > и ≥ соответственно
10 ==   != Операторы равенства = и ≠ соответственно
11 a&b Побитовое И
12 ^ Побитовый XOR (исключающее или)
13 | Побитовое ИЛИ (включающее или)
14 && Логическое И
15 || Логическое ИЛИ
16 a?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