Spec-Zone.ru › C

Представление приоритета операторов в C

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

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

Ссылки

  • Стандарт 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)

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

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

Spec-Zone.ru

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