Этот раздел содержит краткую предварительную информацию об операциях C++. Детальное описание большинства операций на этом этапе ещё невозможно. Графическое представление, название и назначение операции - сейчас этого вполне достаточно. Всё ещё впереди…
Адресные операции, Операции преобразования знака, Побитовые операции, Операция определения размера, Операции увеличения и уменьшения значения, Операции динамического распределения памяти, Операция доступа, Аддитивные операции, Мультипликативные операции, Операции сдвига, Поразрядные операции, Операции сравнения, Логические бинарные операции, Операция присваивания, Операция с тремя операндами, Операция typeid
1.1. Адресные операции
& Операция получения адреса операнда.
Операндом может быть любое l-выражение. Операция возвращает адрес объекта или функции, на который ссылается операнд. Операция невыполнима по отношению к объектам, определённым со спецификатором register, поскольку существует вероятность того, что они не располагаются в памяти и не имеют определённого адреса.
* Операция обращения по адресу или операция косвенного обращения.
Операндом может быть выражение, значением которого является адрес. Операция косвенного обращения называется также операцией разыменования, поскольку позволяет обращаться к объекту не употребляя при этом имени объекта.
1.2. Операции преобразования знака
- Операция унарный минус.
Операндом может быть любое выражение со значением арифметического типа. Операция преобразует положительное значение в отрицательное значение и наоборот.
+ Операция унарный плюс.
Операндом может быть любое выражение со значением арифметического типа. Операция в буквальном смысле ничего не делает. В некоторых источниках её существование объясняется тем, что она ведена для симметрии с унарным минусом. Однако, не совсем понятно, что имеется в виду под понятием симметрии в формальном языке.
В C++ существует возможность присвоения (мы ещё уделим внимание этой интуитивно понятной операции) переменной отрицательного значения. Старательные и аккуратные программисты могут особо подчеркнуть и тот факт, что переменной присвоено положительное значение. Для этого в C++ и была реализована специальная операция унарный плюс.
В формальном языке каждая лексема имеет своё название и назначение. И этот самый плюс-украшение также является операцией. А дальше - рушится иллюзия симметрии унарных операций. Унарный минус работает. Он эквивалентен умножению значения операнда на -1. Унарный плюс эквивалентен умножению значения операнда на +1. Он ничего не делает.
1.3. Побитовые операции
~ Операция инвертирования или побитового отрицания.
Операндом может быть любое выражение интегрального типа. Операция обеспечивает побитовое инвертирование двоичного кода.
! Операция логического отрицания.
Операндом может быть любое выражение со значением арифметического типа. Для непосредственного обозначения логических значений в C++ используются целочисленные значения 0 - ложь и 1 - истина. Кроме того, в логических операциях любое ненулевое значение операнда ассоциируется с единицей. Поэтому отрицанием нулевого значения является 1, т.е. истина, а отрицанием любого ненулевого значения оказывается 0, т.е. ложь.
1.4. Операция определения размера
sizeof Операция определения размера объекта или типа.
В C++ различают два варианта этой операции. В первом случае операндом может быть любое l-выражение. Это выражение записывается справа от символа операции. Значением выражения является размер конкретного объекта в байтах. Во втором случае операндом является имя типа. Это выражение записывается в скобках непосредственно за символом операции. Значением выражения является размер конкретного типа данных в байтах. Результатом этой операции является константа типа size_t. Этот производный целочисленный беззнаковый тип определяется конкретной реализацией.
1.5. Операции увеличения и уменьшения значения
++ Инкремент, или операция увеличения на единицу.
Точнее, на величину, кратную единице, поскольку всё зависит от типа операнда. Операция имеет дополнительный эффект - она изменяет значение операнда. Поэтому операндом здесь может быть только леводопустимое выражение арифметического типа, либо типа указателя. В C++ различают префиксную и постфиксную операции инкремента.
В префиксной форме увеличение значения операнда производится до определения значения выражения. В результате значение выражения и значение операнда совпадают.
В постфиксной форме увеличение значения операнда производится после определения значения выражения. Поэтому значение выражения оказывается меньше значенния операнда.
В выражении с префиксной операцией увеличения знак ++ записывается слева от операнда, в выражении с постфиксной операцией - справа.
Операция инкремента по отношению к указателю увеличивает значение операнда на количество байт, равное длине одного объекта этого типа, то есть действительно на величину, кратную единице.
-- Операция уменьшения значения операнда на величину, кратную единице (декремент).
Эта операция в буквальном смысле симметрична операции инкремента. Имеет аналогичный дополнительный эффект, соответствующие ограничения для операнда (свойство леводопустимости, арифметический тип, либо тип указателя, префиксную и постфиксную формы, изменение значения адреса).
В выражении с префиксной операцией увеличения знак -- записывается слева от операнда, в выражении с постфиксной операцией - справа.
1.6. Операции динамического распределения памяти
new Операция выделения памяти.
Позволяет выделить и сделать доступным участок в динамической памяти. В качестве операнда используется имя типа и, возможно, выражение инициализатор. Операция возвращает адрес размещённого в памяти объекта.
delete Операция освобождения памяти.
Освобождает ранее выделенную с помощью операции new область динамической памяти. В качестве операнда используется адрес освобождаемой области памяти.
1.7. Операция доступа
:: Операция доступа.
Обеспечивает обращение к именованной глобальной области памяти, находящейся вне области видимости. Эта операция применяется при работе с одноимёнными объектами, расположенными во вложенных областях действия имён. Когда объект во внутренней области действия имени скрывает одноименный объект, областью действия которого является файл. Например:
int m; // Глобальная переменная. ::::: int mmm() { int m; // Локальная переменная. m = 100; // Присвоение значения локальной переменной. ::m = 125; // Присвоение значения глобальной // переменной m, находящейся вне области видимости // имени. }
Не следует испытывать никаких иллюзий относительно возможностей этой операции. Операция обеспечивает доступ лишь к глобальным, естественно, ранее объявленным объектам, независимо от степени вложенности области действия. Поэтому она не обладает свойством транзитивности. Выражения вида ::(::(::m)) воспринимаются транслятором как ошибочные.
2.1. Аддитивные операции
+ Операция сложения.
Операция используется с операндами арифметического типа. Один из операндов может иметь тип указателя. В любом случае значением выражения является либо сумма значений, либо сумма адреса и целочисленного значения, кратного размерам данного типа.
Результат сложения указателя с целым числом эквивалентен результату соответствующего количества операций инкремента, пррименённых к укаазателю.
Тип и значение результата выражения любой бинарной операции определяется в зависимости от принятых в C++ соглашений о преобразовании типов, о которых будет сказано ниже.
- Операция вычитания.
Симметричная по отношению к операции сложения бинарная операция.
2.2. Мультипликативные операции
* Операция умножения.
Операндами могут быть выражения арифметического типа. Значением выражения является произведение значений. Тип результата выражения любой бинарной операции определяется в зависимости от принятых в C++ процедур преобразования типов данных.
/ Операция деления.
Операндами могут быть выражения арифметического типа. Значением выражения является частное от деления значения первого операнда на второй операнд. Тип результата выражения любой бинарной операции определяется в зависимости от принятых в C++ процедур преобразования типов данных.
% Операция получения остатка от деления целочисленных операндов (деление по модулю).
Операндами могут быть выражения арифметического типа. В процессе выполнения операции операнды приводятся к целому типу. При неотрицательных операндах остаток положительный. В противном случае знак остатка определяется в зависимости от реализации. Известно, что для Borland C++
15%6=3, (-15)%6=-3, 15%(-6)=3, (-15)%(-6)=-3.
При ненулевом делителе для целочисленных операндов выполняется соотношение
(a/b)*b+a%b=a
2.3. Операции сдвига
Эти операции определены только для целочисленных операндов.
<< Операция левого сдвига.
Операндами могут быть выражения интегрального типа. Значением выражения является битовое представление левого операнда, сдвинутое влево на количество разрядов, равное значению правого операнда. При левом сдвиге на i разрядов первые i разрядов левого операнда теряются, последние i разрядов левого операнда заполняются нулями.
>> Операция правого сдвига.
Операндами могут быть выражения интегрального типа. Значением выражения является битовое представление левого операнда, сдвинутое вправо на количество разрядов, равное значению правого целочисленного операнда. При правом сдвиге на i разрядов первые i разрядов левого операнда заполняются нулями, если левый операнд имеет беззнаковый тип или имеет неотрицательное значение, в противном случае значение определяется реализацией. Последние i разрядов левого операнда теряются.
2.4. Поразрядные операции
Поразрядные операции определены только для целочисленных операндов.
& Поразрядная конъюнкция битовых представлений значений целочисленных операндов.
Операндами могут быть выражения интегрального типа. Значение выражения вычисляется путём побитовых преобразований и зависит от значений соответствующих битов левого и правого операнда. Следующая таблица однозначно определяет операцию поразрядной конъюнкции.
Бит левого операнда | Бит правого операнда | Результат операции & |
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
| Поразрядная дизъюнкция битовых представлений значений целочисленных операндов.
Операндами могут быть выражения интегрального типа. Значение выражения вычисляется путём побитовых преобразований и зависит от значений соответствующих битов левого и правого операнда. Следующая таблица определяет операцию поразрядной дизъюнкции.
Бит левого операнда | Бит правого операнда | Результат операции | |
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
^ Поразрядная исключающая дизъюнкция битовых представлений значений целочисленных операндов.
Операндами могут быть выражения интегрального типа. Значение выражения вычисляется путём побитовых преобразований и зависит от значений соответствующих битов левого и правого операнда. Следующая таблица определяет операцию поразрядной исключающей дизъюнкции.
Бит левого операнда | Бит правого операнда | Результат операции ^ |
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
2.5. Операции сравнения
<,<=,>,>=,==,!= Меньше, меньше равно, больше, больше равно, равно, не равно.
Операции сравнения определены на множестве операндов арифметического типа. Допускается также сравнение значений адресов в памяти ЭВМ. Следующая таблица демонстрирует зависимость результата сравнения от значений операндов Val1 и Val2. Результат сравнения всегда целочисленный и может принимать одно из двух значений: 0 и 1. При этом 0 означает ложь, а 1 - истину.
Операция | 1, если | 0, если |
< | Val1 меньше Val2 | Val1 больше или равно Val2 |
<= | Val1 меньше или равно Val2 | Val1 больше Val2 |
> | Val1 больше Val2 | Val1 меньше или равно Val2 |
>= | Val1 больше или равно Val2 | Val1 меньше Val2 |
== | Val1 равно Val2 | Val1 не равно Val2 |
!= | Val1 не равно Val2 | Val1 равно Val2 |
2.6. Логические бинарные операции
&&,|| И, ИЛИ.
Логические бинарные операции объединяют выражения сравнения со значениями истина (!=0) и ложь (==0). Результат операций приведён в следующей таблице
Первый операнд | Второй операнд | && | || |
Истина | истина | 1 | 1 |
Истина | ложь | 0 | 1 |
Ложь | истина | 0 | 1 |
Ложь | ложь | 0 | 0 |
2.7. Операция присваивания
= Простая форма операции присваивания.
Левый операнд операции присваивания является леводопустимым выражением.
В качестве правого операнда операции присваивания может выступать любое выражение. Значение правого операнда присваивается левому операнду. Значение выражения оказывается равным значению правого операнда. Не существует никаких ограничений на структуру этого операнда. Правый операнд может состоять из множества выражений, соединенных операциями присвоения:
An=…=A3=A2=A1;
где A1, A2, A3, …, An являются выражениями. Для определения значений выражений подобной структуры в C++ существуют правила группирования операндов выражений сложной структуры (эти правила подробно будут описаны ниже). В соответствии с одним из этих правил операнды операции присвоения группируются справа налево:
An=(An-1=…=(A3=(A2=A1))…);
Очевидно, что в таком выражении все операнды, кроме самого правого, должны быть модифицируемыми l-выражениями. В результате выполнения этого выражения операндам An, An-1, … A3, A2 будет присвоено значение операнда A1.
2.8. Специальные формы операций присваивания
В процессе трансляции выражений на этапе генерации кода транслятор строит последовательности машинных кодов, реализующие закодированные в выражениях действия. Например, при трансляции выражения
A = A + 125
транслятор, прежде всего, генерирует код для вычисления значения выражения A + 125 и присвоения результата переменной A. При этом фрагмент кода, вычисляющий адрес переменной A дважды войдёт во множество команд процессора, реализующих это выражение.
В целях упрощения структуры подобных операторов в C++ применяются комбинированные (или сокращённые) формы операторов присваивания.
*= Операция присвоения произведения. A *= B
Присвоение левому операнду произведение значений левого и правого операндов. Операция по своему результату эквивалентна простой форме операции присвоения, у которой правый операнд имеет вид произведения A * B, левый операнд имеет вид A. При этом A является модифицируемым l-выражением:
A = A * B /= Операция присвоения частного от деления. A /= B + 254
Присвоение левому операнду частного от деления значения левого операнда на значение выражения правого операнда. Операция по своему результату эквивалентна простой форме операции присвоения, у которой правый операнд имеет вид
A / (B + 254)
левый операнд прелставляется выражением A. Очевидно, что при этом A должно быть модифицируемым l-выражением:
A = A / (B + 254) %= Операция присвоения остатка от деления. A %= B
Левый операнд должен быть модифицируемым l-выражением.
+= Операция присвоения суммы. A += B
Левый операнд должен быть модифицируемым l-выражением.
-= Операция присвоения разности. A -= B
Левый операнд должен быть модифицируемым l-выражением.
<<= Операция присвоения результата операции побитового сдвига влево на количество бит, равное значению правого целочисленного операнда. A <<= B
Левый операнд должен быть модифицируемым l-выражением.
>>= Операция присвоения результата операции побитового сдвига вправо на количество бит, равное значению правого целочисленного операнда. A <<= B
Левый операнд должен быть модифицируемым l-выражением.
&= Операция присвоения результата поразрядной конъюнкции битовых представлений значений целочисленных операндов. A &= B
Левый операнд должен быть модифицируемым l-выражением.
|= Операция присвоения результата поразрядной дизъюнкции битовых представлений значений целочисленных операндов. A |= B
Левый операнд должен быть модифицируемым l-выражением.
^= Операция присвоения результата поразрядной исключающей дизъюнкции битовых представлений значений целочисленных операндов. A ^= B
Левый операнд должен быть модифицируемым l-выражением.
Специальные формы операций присвоения позволяют не только изменять структуру выражений, но и оптимизировать создаваемый транслятором программный код. Фрагмент кода, определяющий адрес левого операнда выражения встречается в соответствующем множестве команд процессора лишь один раз.
2.9. Операции выбора компонентов структурированного объекта
К операциям выбора компонентов структурированного объекта относятся:
. Операция прямого выбора - точка. -> Операция косвенного выбора.
Об этих операциях будет сказано позже, после определения понятия класса и объекта-представителя класса.
2.10. Операции обращения к компонентам класса
К операциям обращения к компонентам класса относятся:
.* Операция обращения к компоненте класса по имени объекта или ссылки на объект (левый операнд операции) и указателю на компоненту класса (правый операнд операции). ->* Операция обращения к компоненте класса по указателю на объект (левый операнд операции) и указателю на компоненту класса (правый операнд операции). :: Операция доступа к компоненте класса по имени класса и имени компоненты.
2.11. Операция управления процессом вычисления значений
, Операция запятая.
Группирует выражения слева направо. Разделённые запятыми выражения вычисляются последовательно слева направо, в качестве результата сохраняются тип и значение самого правого выражения.
A &= B, A * B, -A
Эта операция формально также является бинарной операцией, хотя операнды этой операции абсолютно не связаны между собой
2.12. Операция вызова функции
() Операция вызова.
Играет роль бинарной операции при вызове функции. Левый операнд представляет собой выражение, значением которого является адрес функции. Правый операнд является разделённым запятыми списком выражений, определяющих значения параметров.
2.13. Операция явного преобразования типа
() Операция преобразования (или приведения) типа.
Эта бинарная операция в контексте так называемого постфиксного выражения и в контексте выражения приведения обеспечивает изменение типа значения выражения, представляемого вторым операндом. Информация о типе, к которому преобразуется значение второго операнда, кодируется первым выражением, которое является спецификатором типа. Существуют две формы операции преобразования типа: каноническая, при которой в скобки заключается первый операнд (в выражениях приведения), и функциональная (в постфиксных выражениях), при которой в скобки заключается второй операнд. При функциональной форме операции преобразования типа спецификатор типа представляется одним идентификатором. Для приввведениия значения к типу unsigned long следует использовать лишь каноническую форму операции преобразования. Механизм преобразования типа рассматривается ниже
2.14. Операция индексации
[] Операция индексации.
Играет роль бинарной операции при индексации элементов массива (определение массива приводится ниже). Левый операнд представляет собой выражение, значением которого является адрес первого элемента массива. Правый операнд является выражением, определяющим значение индекса, т.е. смещения относительно первого элемента массива.
2. Операция с тремя операндами
?: Условная операция.
Единственная в C++ операция с тремя операндами. Первое выражение-операнд располагается слева от знака ?, второе выражение-операнд располагается между знаками ? и :, третье выражение-операнд - справа от знака :. Выполнение условной операции начинается с вычисления значения самого левого операнда. Если его значение оказывается отличным от 0, то вычисляется значение второго операнда, которое и становится значением выражения. Если значение первого операнда оказывается равным 0, то вычисляется значение третьего операнда, и тогда это значение становится значением выражения.
(x < 10)? x = 25: x++
3. Операция typeid
Операция typeid обеспечивает динамическую идентификацию типов. Пока лишь упомянем о её существовании, поскольку её описание требует углублённых познаний в области объектно-ориентированного программирования.
Назад | Содержание | Вперед