Spec-Zone.ru › C++

Порядок приоритета операторов в C++

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

Приоритет Оператор Описание Ассоциативность
1 :: Разрешение области видимости Слева направо →
2 a++ a-- Постфиксный/постфиксный инкремент и декремент
type() type{} Функциональный преобразование типа
a() Вызов функции
a[] Индексирование
. -> Доступ к членам
3 ++a --a Префиксный инкремент и декремент Справа налево ←
+a -a Унарный плюс и минус
! ~ Логическое НЕ и битовое НЕ
(type) Преобразование типа в стиле 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 ^ Битовое ИСКЛЮЧАЮЩЕЕ ИЛИ
13 | Битовое ИЛИ
14 && Логическое И
15 || Логическое ИЛИ
16 a?b:c Условный оператор[примечание 2] Справа налево ←
throw Оператор throw
co_yield выражение yield (C++20)
= Прямое присваивание (по умолчанию для классов C++)
+= -= Составное присваивание с использованием сложения и вычитания
*= /= %= Составное присваивание с использованием умножения, деления и остатка
<<= >>= Составное присваивание с использованием битового сдвига влево и вправо
&= ^= |= Составное присваивание с использованием битовых операций И, ИСКЛЮЧАЮЩЕЕ ИЛИ и ИЛИ
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 не включены, так как они никогда не являются неоднозначными.

END_OF_DOCUMENT_MARKER

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

В языке C условный оператор с тремя операндами имеет более высокий приоритет, чем операторы присваивания. Поэтому выражение e = a < d ? a++ : a = d, которое в C++ разбирается как e = ((a < d) ? (a++) : (a = d)), не будет компилироваться в C из-за грамматических или семантических ограничений языка 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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/operator_precedence

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API