Русская Википедия:Операторы в C и C++

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Язык программирования C++ поддерживает все операторы своего прародителя Си и дополнен новыми операторами и возможностями.

После вычисления первого операнда для неперегруженных операторов «&&», «||» и «,» (оператор «запятая», Шаблон:Lang-en) компилятор вставляет точку следования (Шаблон:Lang-en), гарантирующую, что все побочные эффекты (например, оператор «постфиксный ++») будут выполнены до начала вычисления второго операнда.

Языки с Си-подобным синтаксисом (например, Java, C#, PHP и другие) часто заимствуют операторы Cи/C++ с сохранением не только поведения, но также приоритета и ассоциативности.

Таблицы

В таблицах используются следующие обозначения:

  • «a», «b» и «c»: имена объектов или значения (литералы, значения переменных, возвращаемые значения, lvalue);
  • «Перегружаемый»: возможность перегрузки оператора в языке C++;
  • «Реализован в Си»: существование оператора в языке Си;
  • «R», «T», «S»: имена типов;
  • «Пример»: пример объявления перегруженного оператора;
  • «Член типа T»: определение оператора в виде метода структуры или класса (внутри структуры или класса); пример:
struct T { // или class
   operator float () const;
};
T::operator float () const { /* реализация */ };
  • «Определение вне класса»: определение оператора в виде функции; пример:
#include <iostream>
struct T { // или class
   /* ... */
};
std::ostream & operator << ( std::ostream & a, T const & b ) { /* реализация */ }
  • «Н/Д»: недоступно.

Арифметические операторы

Операция (выражение) Оператор Синтаксис выражения Перегружаемый Реализован в Си Пример
Член типа T Определение вне класса
Присваивание = a = b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:N/a
Сложение + a + b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Вычитание - a - b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Унарный плюс + +a Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Унарный минус - -a Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Умножение * a * b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Деление / a / b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Операция модуль (остаток от деления целых чисел)[note 1] % a % b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Инкремент префиксный ++ ++a width="8%" Шаблон:Yes width="8 %" Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
суффиксный (постфиксный) ++ a++ rowspan="2" Шаблон:Yes rowspan="2" Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
[note 2]
Декремент префиксный -- --a Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
суффиксный (постфиксный) -- a-- rowspan="2" Шаблон:Yes rowspan="2" Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
[note 2]

Операторы сравнения

Операция (выражение) Оператор Синтаксис выражения Перегружаемый Реализован в Си Пример
Член типа T Определение вне класса
Равенство == a == b width="8%" Шаблон:Yes width="8 %" Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Неравенство != a != b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Больше > a > b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Меньше < a < b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Больше или равно >= a >= b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Меньше или равно <= a <= b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp

Логические операторы

Операция (выражение) Оператор Синтаксис выражения Перегружаемый Реализован в Си Пример
Член типа T Определение вне класса
Логическое отрицание, НЕ ! !a width="8%" Шаблон:Yes width="8 %" Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Логическое умножение, И && a && b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Логическое сложение, ИЛИ || a || b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp

Побитовые операторы

Операция (выражение) Оператор Синтаксис выражения Перегружаемый Реализован в Си Пример
Член типа T Определение вне класса
Побитовая инверсия ~ ~a width="8%" Шаблон:Yes width="8 %" Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовое И & a & b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовое ИЛИ (or) | a | b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовое исключающее ИЛИ (xor) ^ a ^ b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовый сдвиг влево[note 3] << a << b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовый сдвиг вправо[note 3][note 4] >> a >> b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp

Составное присваивание

Операция (выражение) Оператор Синтаксис выражения Значение Перегружаемый Реализован в Си Пример
Член типа T Определение вне класса
Сложение, совмещённое с присваиванием += a += b a = a + b width="8%" Шаблон:Yes width="8 %" Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Вычитание, совмещённое с присваиванием -= a -= b a = a - b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Умножение, совмещённое с присваиванием *= a *= b a = a * b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Деление, совмещённое с присваиванием /= a /= b a = a / b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Вычисление остатка от деления, совмещённое с присваиванием[note 1] %= a %= b a = a % b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовое «И» (AND), совмещённое с присваиванием &= a &= b a = a & b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовое «ИЛИ» (or), совмещённое с присваиванием |= a |= b a = a | b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовое «исключающее ИЛИ» (xor), совмещённое с присваиванием ^= a ^= b a = a ^ b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовый сдвиг влево, совмещённый с присваиванием <<= a <<= b a = a << b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Побитовый сдвиг вправо, совмещённый с присваиванием[note 4] >>= a >>= b a = a >> b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp

Операторы работы с указателями и членами класса

Оператор Синтаксис Перегружаемый Реализован в Си Пример
Член типа T Определение вне класса
Обращение к элементу массива a[b] width="8%" Шаблон:Yes width="8 %" Шаблон:Yes Шаблон:Cpp
width="25%" Шаблон:N/a
Непрямое обращение («объект, на который указывает a») *a Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Ссылка («адрес a») &a Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Обращение к члену структуры («член b объекта, на который указывает a») a->b Шаблон:Yes Шаблон:Yes Шаблон:Cpp[note 5]
Шаблон:N/a
Обращение к члену структуры («член b объекта a») a.b Шаблон:No Шаблон:Yes colspan="2" Шаблон:N/a
Член, на который указывает b в объекте, на который указывает a[note 6] a->*b Шаблон:Yes Шаблон:No Шаблон:Cpp Шаблон:Cpp
Член, на который указывает b в объекте a a.*b Шаблон:No Шаблон:No colspan="2" Шаблон:N/a

Другие операторы

Оператор Синтаксис Перегружаемый Реализован в Си Пример
Член типа T Определение вне класса
Функтор a(a1, a2) width="8%" Шаблон:Yes width="8 %" Шаблон:Yes Шаблон:Cpp width="25%" Шаблон:N/a
Оператор «запятая» a, b Шаблон:Yes Шаблон:Yes Шаблон:Cpp Шаблон:Cpp
Тернарная условная операция a ? b : c Шаблон:No Шаблон:Yes colspan="2" Шаблон:N/a
Оператор расширения области видимости a::b Шаблон:No Шаблон:No colspan="2" Шаблон:N/a
Пользовательские литералы (введены в C++11) "a"_b Шаблон:Yes Шаблон:No Шаблон:N/a Шаблон:Cpp
Sizeof (размер) sizeof(a)[note 7]
sizeof(type)
Шаблон:No Шаблон:Yes colspan="2" Шаблон:N/a
Align-of (выравнивание) alignof(type) или _Alignof(type)[note 8] Шаблон:No Шаблон:Yes colspan="2" Шаблон:N/a
Интроспекция typeid(a)
typeid(type)
Шаблон:No Шаблон:No colspan="2" Шаблон:N/a
Приведение типа (type) a rowspan="2" Шаблон:Yes rowspan="2" Шаблон:Yes Шаблон:Cpp Шаблон:N/a
[note 9]
Выделение памяти new type Шаблон:Yes Шаблон:No Шаблон:Cpp Шаблон:Cpp
Выделение памяти для массива new type[n] Шаблон:Yes Шаблон:No Шаблон:Cpp Шаблон:Cpp
Освобождение памяти delete a Шаблон:Yes Шаблон:No Шаблон:Cpp Шаблон:Cpp
Освобождение памяти, занятой массивом delete[] a Шаблон:Yes Шаблон:No Шаблон:Cpp Шаблон:Cpp

Примечания: Шаблон:Примечания

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

В данной таблице указаны приоритеты операторов и их ассоциативность. Операторы, указанные в таблице выше (раньше), имеют более высокий приоритет (приоритет вычисления). При рассмотрении выражения, операторы, имеющие более высокий приоритет, будут вычислены раньше операторов с низким приоритетом. Если несколько операторов указаны в одной ячейке, то они имеют одинаковый приоритет и вычисляются в последовательности, задаваемой ассоциативностью. Приоритеты операторов не изменяются при их перегрузке.


Этой таблицы приоритетов в большинстве случаев бывает достаточно, за исключением следующих случаев. Тернарный оператор «?:» может содержать в среднем выражении оператор «запятая» или присваивание, но код «Шаблон:Cpp» компилятор воспринимает как «Шаблон:Cpp», а не как бессмысленное выражение «Шаблон:Cpp». Таким образом выражение между ? и : воспринимается, как если бы оно было в скобках.

Приоритет Оператор Описание Ассоциативность
1

Наивысший

:: Разрешение области видимости Нет
2 ++ Суффиксный инкремент Слева направо
-- Суффиксный декремент
() Вызов функции
[] Взятие элемента массива
. Выбор элемента по ссылке
-> Выбор элемента по указателю
typeid() RTTI (только C++; см typeid)
const_cast Приведение типа (C++) (см const cast)
dynamic_cast Приведение типа (C++) (см dynamic cast)
reinterpret_cast Каламбур типизации (C++) (см reinterpret_cast)
static_cast Приведение типа (C++) (см static cast)
3 ++ Префиксный инкремент Справа налево
-- Префиксный декремент
+ Унарный плюс
- Унарный минус
! Логическое НЕ
~ Побитовое НЕ
(type) Приведение типа
* Разыменование указателя
& Взятие адреса объекта
sizeof Sizeof (размер)
new, new[] Выделение динамической памяти (C++)
delete, delete[] Освобождение динамической памяти (C++)
4 .* Указатель на член (C++) Слева направо
->* Указатель на член (C++)
5 * Умножение
/ Деление
% Получение остатка от деления
6 + Сложение
- Вычитание
7 << Побитовый сдвиг влево
>> Побитовый сдвиг вправо
8 < Меньше
<= Меньше или равно
> Больше
>= Больше или равно
9 == Равенство
!= Неравенство
10 & Побитовое И (and)
11 ^ Побитовое исключающее ИЛИ (xor)
12 | Побитовое ИЛИ (or)
13 && Логическое И
14 || Логическое ИЛИ
15 ?: Тернарная условная операция Справа налево
= Присваивание
+= Сложение, совмещённое с присваиванием
-= Вычитание, совмещённое с присваиванием
*= Умножение, совмещённое с присваиванием
/= Деление, совмещённое с присваиванием
%= Вычисление остатка от деления, совмещённое с присваиванием
<<= Побитовый сдвиг влево, совмещённый с присваиванием
>>= Побитовый сдвиг вправо, совмещённый с присваиванием
&= Побитовое «И», совмещённое с присваиванием
|= Побитовое «ИЛИ», совмещённое с присваиванием
^= Побитовое «исключающее ИЛИ» (xor), совмещённое с присваиванием
throw Оператор создания исключения (C++)
16 , Оператор «запятая» Слева направо

Описание

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

  • Например, ++x*3 был бы двусмысленным без каких-либо правил приоритетов. По таблице можно сказать, что x сначала связывается с оператором ++, и только затем с оператором *, поэтому независимо от действия оператора ++, это действие только над x (а не над x*3). Таким образом, выражение эквивалентно (++x, x*3).
  • Аналогично с кодом 3*x++, где таблица утверждает, что инкремент применяется только к x а не к 3*x. Функционально это выражение эквивалентно (tmp=x, x++, tmp=3*tmp, tmp), если выразить временную переменную как tmp.
Файл:Precedence 2.png
Приоритеты и связывание

Связывание операторов в стандартах Си и C++ определено через грамматику языка, а не через таблицу. Это может создать конфликт. Например, в языке Си синтаксис условного оператора таков:

logical-OR-expression ? expression : conditional-expression

А в языке C++:

logical-OR-expression ? expression : assignment-expression

Из-за этого выражение:

e = a < d ? a++ : a = d

будет воспринято по-разному в этих двух языках. В Си выражение синтаксически некорректно, так как результат условного оператора не может служить lvalue (то есть, левой частью оператора присваивания).

В C++, выражение будет разобрано как корректное:[1]

e = (a < d ? a++ : (a = d))

Приоритеты побитовых логических операторов несколько неинтуитивны[2]. Концептуально & и | являются такими же арифметическими операторами как * и + соответственно.

Выражение Шаблон:Cpp синтаксически воспринимается как Шаблон:Cpp, но выражение Шаблон:Cpp эквивалентно Шаблон:Cpp. Из-за этого часто требуется пользоваться скобками для явного задания порядка вычислений.

Синонимы операторов в C++

В стандарте C++ определены[3] диграфы для некоторых операторов:

Диграф Эквивалентная строка
and &&
bitand &
and_eq &=
or ||
bitor |
or_eq |=
xor ^
xor_eq ^=
not !
not_eq !=
compl ~

Диграфы могут использоваться точно так же как и операторы, являются синонимами операторов. Например, диграф «Шаблон:Cpp» может использоваться для замены операторов «побитовое И» и «получение адреса» или в определении ссылочных типов. Так, код «Шаблон:Cpp» эквивалентен коду «Шаблон:Cpp».

Стандарт ANSI/ISO C определяет перечисленные диграфы в виде констант Шаблон:Cpp (см. препроцессор). Константы определены в заголовочном файле «iso646.h». Для совместимости с Си стандарт C++ определяет фиктивный заголовочный файл «ciso646».

Примечания

Шаблон:Примечания

Ссылки

Шаблон:Rq Шаблон:Язык программирования Си


Ошибка цитирования Для существующих тегов <ref> группы «note» не найдено соответствующего тега <references group="note"/>