Представление приоритета операторов в 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 | , |
Запятая | Слева направо |
-
Операнд префиксных
++и--не может быть приведением типа. Это правило грамматически запрещает некоторые выражения, которые в любом случае были бы семантически некорректными. Некоторые компиляторы игнорируют это правило и обнаруживают некорректность семантически. -
Операнд
sizeofне может быть приведением типа: выражениеsizeof (int) * pоднозначно интерпретируется как(sizeof(int)) * p, а не какsizeof((int)*p). -
Выражение посередине условного оператора (между
?и:) анализируется так, как будто оно заключено в скобки: его приоритет относительно?:игнорируется. -
Левые операнды операторов присваивания должны быть унарными выражениями (выражениями уровня 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 Выражения
См. также
Порядок вычисления аргументов оператора во время выполнения.
| Общие операторы | ||||||
|---|---|---|---|---|---|---|
| присваивание | инкремент декремент |
арифметические | логические | сравнения | доступ к членам доступа |
другие |
|
|
|
|
|
|
|
| Документация C++ для Приоритет операторов C++ |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/operator_precedence