Унарные операции.
Инкремент и декремент
Инкремент (++) и декремент (--) предназначены для увеличения или уменьшения текущего значения операнда на 1. Обе операции имеют две формы записи: префиксную и постфиксную. В первом случае операция записывается перед операндом, а при выполнении сначала происходит изменение операнда, а затем его значение становится результирующим значением выражения. Во втором случае, операция записывается после операнда, а значением выражения является исходное значение операнда, после чего происходит его изменение.
В общем случае, в качестве операнда выступает L-значение.
Пример 1. Использование операций ++ и --. intmain(){ inta = 11, b = 23; printf(“Значение префиксного выражения: %d\n”, ++b); //Значение префиксного выражения: 24 printf(“Значение постфиксного выражения: %d\n”, b++); //Значение постфиксного выражения: 24 printf(“Значение префиксного выражения: %d\n”, --a); //Значение префиксного выражения: 10 printf(“Значение постфиксного выражения: %d\n”, a--); //Значение постфиксного выражения: 10 printf(“Значение a: %d\n”, a); // Значение a: 9 printf(“Значение b: %d\n”, b); // Значение b: 25 return0; } |
Операция определения размера sizeof
Операция sizeof предназначена для вычисления размера объекта или типа данных, который выражается в байтах.
sizeof имеет две формы записи:
sizeof выражение sizeof(тип_данных) |
В том случае, если необходимо вычислить значение выражения до выполнения операции приведения типа используются скобки.
Пример 2. Использование операции sizeof. #include <iostream.h> intmain(){ floata = 9; cout<< “sizeof(float): ” << sizeof(float) << endl; // sizeof (float): 4 cout<< ”sizeofa: ” << sizeofa << endl; // sizeof a: 4 cout<< “sizeof(a+ 2.2): ” << sizeof(a + 2.2); // sizeof (a+ 2.2): 8 return0; } |
Получение последнего результата связано с тем что вещественные константы по умолчанию имеют тип данных double, а согласно правилам приведения типов, тип переменной и всего выражения приводится к более длинному типу.
Арифметическое, логическое и поразрядное отрицание
Арифметическое отрицание (-) предназначено для изменения знака операнда, принадлежащего целому или вещественному типу данных на противоположный.
Логическое отрицание (!) в результате даёт значение 0 (false) если операнд не равен нулю (true), и 1 (true) если операнд равен нулю. Важно то, что операнд должен быть целого, вещественного или типа указателя.
Поразрядное или побитовое отрицание (~) предназначено для инвертирования каждого разряда в двоичном представлении (бита) целочисленного операнда.
Бинарные операции.
Деление и остаток от деления
Операция деления (/) применяется к операндам, которые принадлежат арифметическим типам. При этом, если оба операнда принадлежат целочисленному типу данных, то результат операции будет округлён до целого, в ином случае тип результата будет определён в соответствии с правилами преобразования.
Операция поиска остатка от деления (%) применима исключительно к целочисленным операндам. Знак результата при этом будет зависеть исключительно от реализации.
Пример 3. Использование операций / и % . #include <stdio.h> intmain(){ intx = 11, у = 4; floatz = 4; printf("Результаты деления: %d %f\n", x/y, x/z); // Результаты деления: 2 2.750000 printf("Остаток: %d\n", x%y); // Остаток: 3 return0; } |
Операции сдвига
Операции сдвига (<< и >>) применяются в отношении целочисленных операндов, сдвигая двоичное представление первого операнда влево или вправо, соответственно, на то количество двоичных разрядов, которое задал пользователь.
При сдвиге влево освободившиеся разряды устанавливаются в 0 (обнуляются). При сдвиге вправо освободившиеся биты обнуляются, если первый операнд беззнакового типа, и знаковым разрядом в противном случае.
Всегда важно иметь ввиду то, что операции сдвига не учитывают переполнение и потерю значимости.
Операции отношения
Операции отношения (<, <=, >, >=, ==,!=) предназначены для сравнения первого операнда со вторым. Операнды могут быть арифметического типа или указателями. В свою очередь результат операции представляется значениями true или false.
Любое значение, которое не является 0, интерпретируется как true.
Операции сравнения на равенство и неравенство имеют меньший приоритет, чем прочие операции сравнения.
Поразрядные операции
К поразрядным операциям относятся поразрядная конъюнкция (&), дизъюнкция (|) и исключающее ИЛИ (^). Эти операции применяются исключительно к целочисленным операндам и работают с их двоичными представлениями.
Важно иметь ввиду то, что операнды сопоставляются побитно.
При использовании поразрядной конъюнкции (&) бит результата будет равен 1 только в том случае, если соответствующие биты обоих операндов будут равны 1. При использовании поразрядной дизъюнкции (|) бит результата будет равен 1 только в том случае, если соответствующий бит хотя бы одного операнда будет равен 1. В свою очередь, при использовании поразрядного исключающего ИЛИ бит результата будет равен 1 только тогда, когда соответствующий бит только одного из операндов будет равен 1.
Пример 4. Использование операций &, | и ^. #include <iostream.h> int main(){ cout << "\n 6 & 5 = " << (6 & 5); //4 cout<< "\n 6 | 5 = " << (6 | 5); //7 cout<< "\n 6 ^ 5 = " << (6 ^ 5); //3 return0; } |
Логические операции
Логические операции включают в себя логическое И (&&) и логическое ИЛИ (||), а их операнды могут иметь арифметический тип данных или быть указателями. Соответственно, операнды в рамках каждой операции могут иметь различные друг от друга типы данных.
При использовании этих операций преобразование типов не осуществляется и каждый операнд оценивается с точки зрения его эквивалентности нулю. Соответственно, операнд, равный нулю, рассматривается как false, а не равный – как true.
При использовании операции && её результат имеет значение true только в том случае, если оба операнда имеют значение true. В свою очередь, при использовании операции || её результат имеет значение true, если хотя бы один из операндов имеет значение true.
Порядок выполнения операций – слева направо.
Если значения первого операнда достаточно, чтобы определить результат операции, второй операнд не вычисляется.
Операции присваивания
К операциям присваивания относятся операции =, +=, -=, /=, *= и т.д. Они могут использоваться в программе как законченные операторы.
Синтаксис использования операции присваивания выглядит следующим образом:
операнд_1 = операнд_2 |
В данном случае первый операнд обязательно должен быть L-значением, а второй R-значением (выражением). При выполнении операции присваивания сначала осуществляется вычисление выражения, стоящего в правой части операции, а потом его результат записывается в область памяти, определённую в левой части. Соответственно, то, что ранее хранилось в этой области памяти теряется.
Существует некоторое мнемоническое правило: «присваивание – это передача данных «налево».»
В сложных операциях присваивания (+=, *=, /= и т.п.) при вычислении выражения, стоящего в правой части, используется и L-значение из левой части. Например, при умножении с присваиванием второй оператор будет умножен на первый и результат будет записан в него же.
Иными словами, выражение вида: a *= b – это более сжатая версия выражения a = a * b.
Пример 5. Использование операций присваивания. #include<iostream.h> intmain(){ inta = 3, b=1, c=10; a += b; b = b + 4; с /= b; cout<< "a = " << a; cout<< "\t b = " << b << endl; // a = 4 cout<< "\t с = " << с; // c = 2 return 0; } |
Тернарная операций.
Условная операция ?: имеет три операнда а потому называется тернарной.
Синтаксис операции имеет следующий вид:
операнд_1? операнд_2: операнд_3 |
В данном случае первый операнд может иметь арифметический тип или же быть указателем, соответственно операнд, равный нулю, рассматривается как false, а не равный – как true.
Если результат вычисления операнда 1 равен true, то в качестве результата условной операций будет выступать значение второго операнда, в ином случае – третьего. Типы второго и третьего операнда могут отличаться, а вычисление значения осуществляется только для одного из них.
Эта операция является сокращённым вариантом условного оператора if.
Пример 6. Использование операции?:. #include<stdio.h> intmain(){ inta = 11, b = 4, max; max = (b > a)? b: a; printf("Наибольшее число: %d", max); //Наибольшее число: 11 return0; } |
Приоритет операций.
Все операции выполняются в соответствии со своим приоритетом. Для того, чтобы изменить порядок выполнения используются круглые скобки. В том случае если в одном выражении записано несколько операций, имеющих одинаковый приоритет, унарные операции, условная операция и операции присваивания выполняются справа налево, а все остальные – слева направо.
В том случае если используются выражения вида: a = b = c. Сначала осуществляется вычисление выражения b = c, затем его результат становится правым операндом для операции присваивания переменной a.
Унарные операции имеют наивысший приоритет в сравнении с бинарными и тернарными операциями.
Операция | Краткое описание |
++ | увеличение на 1 |
-- | уменьшение на 1 |
sizeof | размер |
~ | поразрядное отрицание |
! | логическое отрицание |
- | арифметическое отрицание (унарный минус) |
+ | унарный плюс |
& | взятие адреса |
* | разадресация (косвенная адресация); |
new | выделение памяти |
Delete | освобождение памяти |
(type) | преобразование типа |
Приведение типов.
Если операнды, входящие в выражение, имеют разный тип, то перед вычислениями выполняются преобразования типов по определенным правилам, обеспечивающим преобразование более коротких типов в более длинные для сохранения значимости и точности.
Преобразования бывают двух типов:
- изменяющие внутреннее представление величин (с потерей точности и без потери точности);
- изменяющие только интерпретацию внутреннего представления.
К первому типу относится, например, преобразование целого числа в вещественное, ко второму — преобразование знакового целого в беззнаковое.
В любом случае величины типов char, signed char, unsigned char, short int и unsigned short int преобразуются в тип int, если он может представить все значения, или в unsigned int в противном случае. Затем операнды преобразуются к типу наиболее длинного из них, после чего он используется как тип результата.
Программист всегда может задать преобразования типа в явном виде.