Spec-Zone.ru › C

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

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

Приоритет Оператор Описание Ассоциативность
1 ++ -- Постфиксный инкремент и декремент Слева направо
() Вызов функции
[] Индексация массива
. Доступ к члену структуры и объединения
-> Доступ к члену структуры и объединения через указатель
(type){list} Составной литерал(C99)
2 ++ -- Префиксный инкремент и декремент[1] Справа налево
+ - Унарный плюс и минус
! ~ Логическое НЕ и побитовое НЕ
(type) Приведение типа
* Разыменование
& Взятие адреса
sizeof Размер объекта[2]
_Alignof Требование к выравниванию(C11)
3 * / % Умножение, деление и остаток от деления Слева направо
4 + - Сложение и вычитание
5 << >> Побитовый сдвиг влево и вправо
6 < <= Для операторов отношения < и ≤ соответственно
> >= Для операторов отношения > и ≥ соответственно
7 == != Для операторов отношения = и ≠ соответственно
8 & Побитовое И
9 ^ Побитовое исключающее ИЛИ
10 | Побитовое ИЛИ
11 && Логическое И
12 || Логическое ИЛИ
13 ?: Тернарный условный оператор[3] Справа налево
14[4] = Простое присваивание
+= -= Присваивание суммы и разности
*= /= %= Присваивание произведения, частного и остатка от деления
<<= >>= Присваивание результата побитового сдвига влево и вправо
&= ^= |= Присваивание результата побитовых И, исключающего ИЛИ и ИЛИ
15 , Запятая Слева направо
  1. Операнд префиксного ++ и -- не может быть приведением типа. Это правило грамматически запрещает некоторые выражения, которые в любом случае были бы семантически недопустимыми. Некоторые компиляторы игнорируют это правило и обнаруживают недопустимость на семантическом уровне.
  2. Операнд sizeof не может быть приведением типа: выражение sizeof (int) * p однозначно интерпретируется как (sizeof(int)) * p, но не как sizeof((int)*p).
  3. Выражение в средней части условного оператора (между ? и :) разбирается так, как если бы оно было заключено в скобки: его приоритет относительно ?: не учитывается.
  4. Левые операнды операторов присваивания должны быть унарными выражениями (выражениями уровня 2 без приведения типа). Это правило грамматически запрещает некоторые выражения, которые в любом случае были бы семантически недопустимыми. Многие компиляторы игнорируют это правило и обнаруживают недопустимость на семантическом уровне. Например, e = a < d ? a++ : a = d — выражение, которое нельзя разобрать из-за этого правила. Однако многие компиляторы игнорируют это правило и разбирают его как e = ( ((a < d) ? (a++) : a) = d ), после чего выдают ошибку, поскольку выражение семантически недопустимо.

При разборе выражения оператор, указанный в строке таблицы, связывается со своими аргументами теснее (как если бы они были заключены в скобки), чем любой оператор, расположенный в строке ниже. Например, выражение *p++ разбирается как *(p++), а не как (*p)++.

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

Примечания

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

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

В C++ условный оператор имеет тот же приоритет, что и операторы присваивания, а для префиксных ++ и -- и операторов присваивания не действуют ограничения на их операнды.

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

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
    • A.3.1 Выражения
  • Стандарт C17 (ISO/IEC 9899:2018):
    • A.2.1 Выражения
  • Стандарт C11 (ISO/IEC 9899:2011):
    • A.2.1 Выражения
  • Стандарт C99 (ISO/IEC 9899:1999):
    • A.2.1 Выражения
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
    • A.1.2.1 Выражения

См. также

Порядок вычисления аргументов операторов во время выполнения.

Распространённые операторы
присваивание инкремент
декремент
арифметические логические сравнения доступ
к членам
прочие

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->b a.b

a(...) a, b (type) a a ? b : c sizeof

_Alignof
(начиная с C11)
(до C23)

alignof
(начиная с C23)

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

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

Spec-Zone.ru

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