Это список операторы в языках программирования C и C++ . Все перечисленные операторы существуют в C ++; четвертый столбец «Включено в C» указывает, присутствует ли оператор также в C. Обратите внимание, что C не поддерживает перегрузку операторов .
Если не перегружен, для операторов ,
||
и ,
(оператор запятая ), после вычисления первого операнда находится точка последовательности.
C ++ также содержит операторы преобразования типов const_cast
, static_cast
, dynamic_cast
и reinterpret_cast <146.>. Форматирование этих операторов означает, что их уровень приоритета не важен.
Большинство операторов, доступных в C и C ++, также доступны в других языках семейства C, таких как C#, D, Java, Perl и PHP с тем же приоритетом, ассоциативностью и семантикой.
Для целей этих таблиц a
, b
и c
представляют допустимые значения (литералы, значения из переменных или возвращаемое значение), имена объектов, или lvalues, в зависимости от ситуации. R
, S
и T
обозначают любой тип (типы), а K
- тип класса или перечислимый тип.
Имя оператора | Синтаксис | Возможна перегрузка в C ++ | Включено. в C | примеры прототипов C ++ | ||
---|---|---|---|---|---|---|
Как член K | Определения внешнего класса | |||||
Базовое присвоение | a =b | Да | Да | R K :: operator = (S b); | Н / Д | |
Сложение | a +b | Да | Да | RK :: оператор + (S b); | R оператор + (K a, S b); | |
Вычитание | a -b | Да | Да | RK :: operator - (S b); | R operator - (K a, S b); | |
Унарный плюс (целочисленное продвижение ) | +a | Да | Да | RK :: operator + (); | R operator + (K a); | |
Унарный минус (аддитивный обратный ) | -a | Да | Да | RK :: operator - (); | R operator - (K a); | |
Умножение | a *b | Да | Да | RK :: operator * (S b); | R оператор * (K a, S b); | |
Разделение | a /b | Да | Да | RK :: operator / (S b); | Оператор R / (K a, S b); | |
по модулю (целочисленный остаток) | a %b | Да | Да | RK :: operator% (S b); | R оператор% (K a, S b); | |
Приращение | Префикс | ++a | Да | Да | R K :: operator ++ (); | R operator ++ (Ka); |
Postfix | a++ | Да | Да | RK: : operator ++ (int); | R operator ++ (K a, int); | |
Примечание: C ++ использует безымянный фиктивный параметр int , чтобы различать операторы префиксного и постфиксного приращения. | ||||||
Уменьшение | Префикс | --a | Да | Да | Оператор R K :: - (); | Оператор R - (K a); |
Постфикс | a-- | Да | Да | RK :: operator - (int); | R operator - (K a, int); | |
Примечание: C ++ использует безымянный фиктивный параметр int , чтобы различать префиксные и постфиксные операторы декремента. |
Имя оператора | Синтаксис | Возможна перегрузка в C ++ | Включено. в C | Примеры прототипов | ||
---|---|---|---|---|---|---|
Как член K | Определения внешнего класса | |||||
Равно | a ==b | Да | Да | bool K :: operator == (S const b) const; | оператор bool == (K const a, S const b); | |
Не равно | a !=b . a not_eqb | Да | Да | bool K :: operator! = (S const b); bool K :: operator! = (S const b) const; | bool operator! = (K const a, S const b); | |
Больше, чем | a>b | Да | Да | bool K :: operator>(S const b) const; | bool operator>(K const a, S const b); | |
Меньше | a | Да | Да | bool K :: operator <(S constb) const; | bool operator <(K consta, S constb); | |
Больше или равно | a>=b | Да | Да | bool K :: operator>= (S const b) const; | bool operator>= (K const a, S const b); | |
Меньше или равно | a <=b | Да | Да | bool K :: operator <=(S constb) const; | bool operator <=(K consta, S constb); | |
Трехстороннее сравнение | a <=>b | Да | Нет | ул. d :: weak_equality K :: operator <=>(const S b); | std :: weak_equality operator <=>(const K a, const S b); | |
Примечание: у оператора всего 6 возвращаемые типы: std :: weak_equality , std :: strong_equality , std :: partial_ordering , std :: weak_ordering , std :: strong_ordering и std :: common_comparison_category |
Имя оператора | Синтаксис | Возможна перегрузка в C ++ | Включено. в C | примерах прототипов C ++ | ||
---|---|---|---|---|---|---|
Как член K | Определения внешних классов | |||||
Логическое отрицание (НЕ) | !a . не a | Да | Да | bool K :: operator! (); | bool operator! (K a); | |
Логическое И | a b . a и b | Да | Да | bool K :: operator (S b); | логический оператор (K a, S b); | |
Логическое ИЛИ | a ||b . a orb | Да | Да | логический оператор K :: || (S b) ; | логический оператор || (K a, S b); |
Имя оператора | Синтаксис | Возможна перегрузка в C ++ | Включено. в C | Экзамен прототипа ples | ||
---|---|---|---|---|---|---|
Как член K | Определения внешних классов | |||||
Побитовое НЕ | ~a . Compl a | Да | Да | RK :: operator ~ (); | R оператор ~ (K a); | |
Побитовое И | a b . a бит и b | Да | Да | RK :: operator (S b); | R оператор (K a, S b); | |
Поразрядное ИЛИ | a |b . a битор b | Да | Да | RK :: operator | (S b); | R operator | (K a, S b); | |
Побитовое исключающее ИЛИ | a ^b . a xor b | Да | Да | RK :: operator ^ (S b); | R operator ^ (K a, S b); | |
Побитовый сдвиг влево | a < | Да | Да | RK :: operator <<(S b); | R operator <<(K a, S b); | |
Побитовый сдвиг вправо | a>>b | Да | Да | RK :: operator>>(S b); | R operator>>(K a, S b); |
Имя оператора | Синтаксис | Значение | Возможна перегрузка в C ++ | Включено. в C | примеры прототипов C ++ | ||
---|---|---|---|---|---|---|---|
Как член K | Определения внешних классов | ||||||
Добавление присваивания | a +=b | a =a +b | Да | Да | R K :: operator + = (S b); | R operator + = (K a, S b); | |
Присваивание вычитания | a -=b | a =a -b | Да | Да | R K :: operator - = (S b); | R operator - = (K a, S b); | |
Присвоение умножения | a *=b | a =a *b | Да | Да | R K :: operator * = (S b); | R operator * = (K a, S b); | |
Назначение деления | a /=b | a =a /b | Да | Да | R K :: operator / = (S b); | R operator / = (K a, S b); | |
Присвоение по модулю | a %=b | a =a %b | Да | Да | RK :: operator% = (S b); | R operator% = (K a, S b); | |
Побитовое И присваивание | a =b . a and_eq b | a =a b | Да | Да | RK: : operator = (S b); | R operator = (K a, S b); | |
Назначение побитового ИЛИ | a |=b . a or_eq b | a =a |b | Да | Да | RK :: operator | = (S b); | R operator | = (K a, S b); | |
Побитовое присвоение XOR | a ^=b . a xor_eq b | a =a ^b | Да | Да | R K :: operator ^ = (S b); | R operator ^ = (K a, S b); | |
Назначение побитового сдвига влево | a <<=b | a =a < | Да | Да | RK: : operator <<=(S b); | R operator <<=(Ka, S b); | |
Назначение побитового сдвига вправо | a>>= b | a =a>>b | Да | Да | RK :: operator>>= (S b); | R operator>>= (K a, S b); |
O имя оператора | Синтаксис | Возможна перегрузка в C ++ | Включено. в C | Примеры прототипов C ++ | ||
---|---|---|---|---|---|---|
Как член K | Снаружи определения классов | |||||
Нижний индекс | a[b] | Да | Да | R K :: operator (S b); . | Н / Д | |
Косвенное обращение ("объект, на который указывает символ") | *a | Да | Да | R K :: operator * (); | R operator * (K a); | |
Address-of ("адрес a") | a | Да | Да | R * K :: operator (); | R * operator (K a); | |
Разыменование структуры ("элемент b объекта, на который указывает a") | a->b | Да | Да | R * K :: operator ->(); . | Н / Д | |
Ссылка на структуру («элемент b объекта a») | a.b | No | Да | Н / Д | ||
Элемент, выбранный параметром b объекта, на который указывает | a->* b | Да | Нет | Оператор R K :: ->* (S b); | R operator ->* (K a, S b); | |
Элемент объекта a, выбранный b | a.*b | No | Нет | N / A |
Имя оператора | Синтаксис | Возможна перегрузка в C ++ | Включено. в C | Примеры прототипов | ||
---|---|---|---|---|---|---|
Как член K | Определения внешних классов | |||||
Функция вызов. См. Функциональный объект. | a(a1, a2 ) | Да | Да | RK :: operator () (S a, T b,...); | Н / Д | |
Запятая | a,b | Да | Да | RK :: operator, (S b); | R operator, (K a, S b); | |
Тернарная условная | a ?b :c | No | Да | Н / Д | ||
Разрешение области | a::b | No | Нет | Н / Д | ||
Определяется пользователем литералы. начиная с C ++ 11 | "a"_b | Да | Нет | Н / Д | Оператор R "" _b (T a) | |
Sizeof | sizeof (a) . sizeof (type) | No | Да | Н / Д | ||
Размер пакета параметров. с C ++ 11 | sizeof... (Args) | No | Нет | N / A | ||
. с C ++ 11 | alignof (type) . или _Alignof (тип) | No | Да | Н / Д | ||
Идентификация типа | typeid (a) . typeid (тип) | No | Нет | Н / Д | ||
Преобразование (приведение в стиле C) | (тип) a | Да | Да | K :: operator R (); | Н / Д | |
Преобразование | тип (a) | No | Нет | Примечание: ведет себя как const_cast / static_cast / reinterpret_cast | ||
static_cast преобразование | static_cast | Да | Нет | K :: operator R (); . явный K :: оператор R (); начиная с C ++ 11 | Н / Д | |
Примечание: для пользовательских преобразований тип возвращаемого значения неявно и обязательно соответствует имени оператора. | ||||||
динамическое приведение преобразование | динамическое_кастирование | No | Нет | Н / Д | ||
const_cast преобразование | const_cast | No | Нет | Н / Д | ||
reinterpret_cast преобразование | reinterpret_cast | No | Нет | Н / Д | ||
Выделить хранилище | новый тип | Да | Нет | void * K :: operator new (size_t x); | void * operator new ( size_t x); | |
Выделить хранилище (массив) | newtype[n] | Да | Нет | void * K :: operator new (size_t a); | void * operator new (size_t a); | |
Освободить память | delete a | Да | Нет | void K :: operator delete (void * a); | void operator delete ( void * a); | |
Освободить память (массив) | удалить a | Да | Нет | void K :: operator delete (void * a); | void operator delete ( void * a); | |
Проверка исключений. начиная с C ++ 11 | noexcept (a) | No | Нет | Н / Д |
Примечания:
В следующей таблице перечислены приоритет и ассоциативность Все операторы на языках C и C ++ (когда операторы также существуют в Java, Perl, PHP и для многих других недавних языков приоритет такой же, как и данный). Операторы перечислены сверху вниз в порядке убывания приоритета. Нисходящий приоритет относится к приоритету группировки операторов и операндов. Учитывая выражение, оператор, который указан в некоторой строке, будет сгруппирован перед любым оператором, который указан в строке ниже. Операторы, находящиеся в одной ячейке (в ячейке может быть несколько строк операторов), группируются с одинаковым приоритетом в заданном направлении. Приоритет оператора не зависит от перегрузки.
Синтаксис выражений в C и C ++ определяется грамматикой структуры фраз . Приведенная здесь таблица была выведена из грамматики. Для стандарта ISO C 1999 в примечании 71 раздела 6.5.6 указано, что грамматика C, предусмотренная спецификацией, определяет приоритет операторов C, а также говорится, что приоритет операторов, вытекающий из грамматики, точно соответствует порядку разделов в спецификации:
"Синтаксис [C] [т. Е. Грамматика] определяет приоритет операторов при оценке выражения, который совпадает с порядком основных подпунктов этого подпункта, высший приоритет сначала. "
Таблица приоритетов, хотя в основном адекватная, не может разрешить некоторые детали. В частности, обратите внимание, что тернарный оператор допускает любое произвольное выражение в качестве своего среднего операнда, несмотря на то, что он указан как имеющий более высокий приоритет, чем присвоение и операторы запятой. Таким образом, a? b, c: d
интерпретируется как a? (b, c): d
, а не как бессмысленное (a? b), (c: d)
. Таким образом, выражение в середине условного оператора (между ?
и :
) анализируется, как если бы p озвучены. Также обратите внимание, что непосредственный, без скобок результат выражения приведения C не может быть операндом sizeof
. Следовательно, sizeof (int) * x
интерпретируется как (sizeof (int)) * x
, а не sizeof ((int) * x)
.
Приоритет | Оператор | Описание | Ассоциативность |
---|---|---|---|
1 наивысшее | :: | Разрешение области (только C ++) | Нет |
2 | ++ | Постфиксное приращение | Слева направо |
-- | Постфиксный декремент | ||
() | Вызов функции | ||
| Индексирование массива | ||
. | Выбор элемента по ссылке | ||
-> | Выбор элемента с помощью указателя | ||
typeid () | Тип времени выполнения информация (только C ++) (см. typeid ) | ||
const_cast | Приведение типа (только C ++) (см. const_cast ) | ||
dynamic_cast | Приведение типа (только C ++) (см. динамическое приведение ) | ||
reinterpret_cast | приведение типа (только C ++) (см. reinterpret_cast ) | ||
static_cast | приведение типа (только C ++) (см. static_cast ) | ||
3 | ++ | приращение префикса | Справа налево |
-- | Префиксный декремент | ||
+ | Унарный плюс | ||
- | Унарный минус | ||
! | Логическое НЕ | ||
~ | Побитовое НЕ (дополнение до единицы) | ||
(тип) | Приведение типа | ||
* | Косвенное обращение (разыменование) | ||
| Address-o f | ||
sizeof | Sizeof | ||
_Alignof | Требование выравнивания (начиная с C11) | ||
new , new | Динамическое распределение памяти (только C ++) | ||
delete , delete | Динамическое освобождение памяти (только C ++) | ||
4 | .* | Указатель на член (только C ++) | Слева направо |
->* | Указатель на член ( Только C ++) | ||
5 | * | Умножение | Слева направо |
/ | Деление | ||
% | По модулю (остаток) | ||
6 | + | Сложение | Слева направо |
- | Вычитание | ||
7 | << | Побитовое сдвиг влево | Слева направо |
>> | Побитовое сдвиг вправо | ||
8 | <=> | Трехстороннее сравнение (введено в C ++ 20 - только C ++) | Слева направо |
9 | < | Меньше | Слева направо |
<= | Меньше или равно | ||
> | Больше | ||
>= | Больше или равно | ||
10 | == | Равно | Слева направо |
!= | Не равно | ||
11 |
| Побитовое И | Слева направо справа |
12 | ^ | Поразрядное ИЛИ (исключающее ИЛИ) | Слева направо |
13 | | | Поразрядное ИЛИ (включительно ИЛИ) | Слева направо |
14 |
| Логическое И | L eft-to-right |
15 | || | Логическое ИЛИ | Слева направо |
16 | ?: | Тройное условное (см. ?: ) | Справа налево |
= | Прямое присвоение | ||
+= | Присвоение по сумме | ||
-= | Присвоение по разнице | ||
*= | Присвоение по продукту | ||
/= | Присвоение по частному | ||
%= | Присвоение по остатку | ||
<<= | Присвоение с помощью побитового сдвига влево | ||
>>= | Назначение с помощью побитового сдвига вправо | ||
= | Назначение с помощью побитового И | ||
^= | Назначение с помощью побитового ИЛИ | ||
|= | Назначение с помощью побитового ИЛИ | ||
throw | Оператор выброса (генерирование исключений, только C ++) | ||
17 самый низкий | , | Запятая | Слева направо |
Таблица приоритета определяет порядок привязки в связанных выражениях, если он явно не указан круглыми скобками.
++ x * 3
является неоднозначным без какого-либо правила (правил) приоритета. Таблица приоритетов сообщает нам, что: xболее жестко «привязан» к ++, чем к *, так что все, что ++делает (сейчас или позже - см. ниже), он делает это ТОЛЬКО с x(а не с x * 3
); он эквивалентен (++ x
, x * 3
).3 * x ++
, где хотя пост-исправление ++разработан, чтобы действовать ПОСЛЕ оценки всего выражения, таблица приоритетов дает понять, что ТОЛЬКО xувеличивается (а НЕ 3 * x
). Фактически, выражение (tmp = x ++
, 3 * tmp
) оценивается с tmp, являющимся временным значением. Функционально это эквивалентно чему-то вроде (tmp = 3 * x
, ++ x
, tmp
).Многим операторам, содержащим многосимвольные последовательности, присваиваются «имена», составленные из имени оператора каждого символа. Например, + =
и - =
часто называют плюс равным (я) и минус равным (я), вместо более подробных "присвоение путем сложения" и "присвоение путем вычитания". ". Связывание операторов в C и C ++ определяется (в соответствующих Стандартах) грамматикой факторизованного языка, а не таблицей приоритетов. Это создает некоторые тонкие конфликты. Например, в C синтаксис условного выражения:
выражение-логическое ИЛИ? выражение: условное-выражение
, а в C ++ это:
логическое-ИЛИ-выражение? выражение: выражение-присваивания
Следовательно, выражение:
e = a < d ? a++ : a = d
анализируется по-разному на двух языках. В C это выражение является синтаксической ошибкой, потому что синтаксис выражения присваивания в C следующий:
unary-expression '=' assignment-expression
В C ++ он анализируется как:
e = ( a < d ? a++ : (a = d))
, которое является допустимым выражением.
Если вы хотите использовать оператор-запятую в одном аргументе функции, назначении переменных или другом списке, разделенном запятыми, вам необходимо использовать круглые скобки, например:
int a = 1, b = 2, weirdVariable = (++ a, b), d = 4;
Приоритет побитовых логических операторов имеет подверглись критике. Концептуально и | являются арифметическими операторами, такими как * и +.
Выражение a b == 7
синтаксически разбирается как a (b == 7)
, тогда как выражение a + b == 7
разбирается как (a + b) == 7
. Это требует, чтобы скобки использовались чаще, чем в противном случае.
Исторически не существовало синтаксического различия между побитовыми и логическими операторами. BCPL, B и ранняя версия C, операторы ||
не существовали. Вместо этого |
имеет разное значение в зависимости от того, используются ли они в «контексте истинного значения» (т.е. когда ожидалось логическое значение, например в if (a == b c) {...}
он вёл себя как логический оператор, но в c = a b
он вёл себя как побитовый). Он был сохранен для сохранения обратной совместимости с существующими установками.
Более того, в C ++ (и более поздних версиях C) операции равенства, за исключением оператора трехстороннего сравнения, yield bool значения типа, которые концептуально представляют собой один бит (1 или 0) и, как таковые, не принадлежат должным образом к «побитовым» операциям.
C ++ определяет определенные ключевые слова, которые действуют как псевдонимы для ряда операторов:
Keyword | Operator |
---|---|
и |
|
and_eq | = |
bitand |
|
bitor | | |
comp | ~ |
not | ! |
not_eq | != |
or | || |
or_eq | |= |
xor | ^ |
xor_eq | ^= |
Их можно использовать точно так же, как символы пунктуации, которые они заменяют, поскольку они - это не один и тот же оператор под другим именем, а скорее простая замена токена для имени (символьной строки) соответствующего оператора. Это означает, что выражения (a>0, а не flag)
и (a>0 ! Flag)
имеют одинаковые значения. Это также означает, что, например, ключевое слово bitand
можно использовать для замены не только побитового оператора И, но также оператора адресации, и оно может даже использоваться для указания ссылочных типов (например, int бит и ref = n
). Спецификация ISO C допускает использование этих ключевых слов в качестве макросов препроцессора в файле заголовка iso646.h
. Для совместимости с C C ++ предоставляет заголовок ciso646
, включение которого не имеет никакого эффекта.