Приоритет операторов C++
В следующей таблице перечислены приоритет и ассоциативность операторов C++. Операторы перечислены сверху вниз в порядке убывания приоритета.
- ↑ Операнд
sizeof
не может быть приведением типа в стиле C: выражение sizeof(int)*p однозначно интерпретируется как (sizeof(int))*p, но не sizeof((int)*p). - ↑ Выражение в середине условного оператора (между
?
и:
) анализируется, как если бы оно было заключено в скобки: его приоритет относительно?:
игнорируется.
При синтаксическом анализе выражения оператор, указанный в некоторой строке приведённой выше таблицы, будет более тесно связан со своими аргументами (как в случае применения скобок), чем любой оператор из строк, расположенных ниже, с более низким приоритетом. Например, выражения 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 |
+a |
!a |
a == b |
a[...] |
вызов функции |
a(...) | ||||||
запятая | ||||||
a, b | ||||||
условный | ||||||
a ? b : c | ||||||
Специальные операторы | ||||||
static_cast приводит один тип к другому совместимому типу |
Документация C по Приоритет операторов C
|