C_Kurs_Lekt / C_I_семестр / 02_Операции_в_Си
.pdfЛысый Д.А. Лекция(продолжение) Операции в Си |
1 |
ОПЕРАЦИИ ЯЗЫКА СИ
Таблица приоритетов рангов операций С
|
Ðàíã |
Операции |
|
|
|
Ассоциативность |
||
|
1 |
() [] . |
|
|
|
-> |
||
|
2 |
! ~ + - ++ -- & * (тип) sizeof тип() (функциональное преобразо- |
<- |
|||||
|
|
вание типа) |
|
|
|
|
||
|
3 |
* / % (мультипликативные бинарные операции) |
-> |
|||||
|
4 |
+ - (аддитивные бинарные операции) |
-> |
|||||
|
5 |
<< |
>> |
|
|
|
|
-> |
|
6 |
< |
<= |
>= |
> |
|
|
-> |
|
7 |
== |
!= |
|
|
|
|
-> |
|
8 |
& |
|
|
|
|
|
-> |
|
9 |
^ |
|
|
|
|
|
-> |
|
10 |
| |
|
|
|
|
|
-> |
|
11 |
&& |
|
|
|
|
|
-> |
|
12 |
|| |
|
|
|
|
|
-> |
|
13 |
?: (условная операция) |
|
<- |
||||
|
14 |
= |
*= |
/= |
%= += |
-= |
&= ^= |= <<= >>= |
<- |
|
15 |
, (операция запятая) |
|
-> |
||||
Отношения и логические операции |
|
|
||||||
|
Знаки операций отношения: |
|
|
|
||||
== |
равно; |
|
|
!= |
неравно; |
|
||
< |
меньше, чем; |
<= |
меньше или равно; |
|
||||
> |
больше, чем; |
|
>= |
больше или равно. |
|
Логический тип в языке Си отсутствует, поэтому принято, что отношение имеет любое ненулевое положительное значение (обычно 1), если оно истинно, и равно 0, если оно ложно. Ничто не противоречит применению логических операций к це-
лочисленным значениям. |
|
|
|
|
|
||
Примеры: |
|
|
|
|
|
||
5<7 |
равняется 1; |
|
|
|
|
|
|
5>7 |
равняется 0; |
|
|
|
|
|
|
5==7 |
равняется 0; |
|
|
|
|||
|
Логических операций в языке Си три. Приведем таблицы истинности этих операций. |
||||||
Таблицы истинности логических операций |
|
|
|
||||
! - отрицание, т.е. логическое НЕ ; |
|
|
|
||||
|
|
Выражение |
|
|
|
Результат (!Выражение) |
|
|
|
|
0 |
|
|
|
1 |
|
|
ненулевое |
|
|
|
0 |
|
|
&& -конъюнкция, т.е. логическое И; |
|
|
|
|||
|
|
выражение1 |
|
|
выражение2 |
выражение1&& выражение2 |
|
|
|
0 |
|
|
0 |
|
0 |
|
|
0 |
|
|
ненулевое |
0 |
|
|
|
ненулевое |
|
|
0 |
|
0 |
|
|
ненулевое |
|
|
ненулевое |
1 |
|
|
|| - дизъюнкция, т.е. логическое ИЛИ |
|
|
|
|||
|
|
выражение1 |
|
|
выражение2 |
выражение1 || выражение2 |
|
|
|
0 |
|
|
0 |
|
0 |
|
|
0 |
|
|
ненулевое |
1 |
|
|
|
ненулевое |
|
|
0 |
|
1 |
|
|
ненулевое |
|
|
ненулевое |
1 |
|
5!=7 |
равняется 1; |
|
|
|
|||
7!=5 || 7<5 |
равняется 1; |
|
|
|
|||
56>5 && 3*15>44 && 45+1>3 |
равняется 1. |
|
Поразрядные операции:
~поразрядное инвертирование внутреннего двоичного кода целочисленного аргумента (побитовое отрицание)
—«переворачивает» значение каждого бита на противоположное. Так, если А в двоичном виде представляется как 01101100, то ~ А станет 10010011:
~ [1] = 0 ~ [0] = 1
Квадратные скобки вокруг аргументов обозначают действие над одним битам.
& поразрядная конъюнкция (И) битовых представлений целочисленных операндов, так называемое логическое умножение
[0]& [1] = [1] & [0] = [0]
[0]& [0] = [0]
[1]& [1] = [1]
Лысый Д.А. Лекция(продолжение) Операции в Си |
2 |
|
Квадратные скобки вокруг аргументов обозначают действие над одним битам. |
||||||
|
Пример: (6 & 4) = 4, (6 & 1) = 0. Рассмотрим 6 и 4 как двоичные числа: |
||||||
|
0000110 |
(6) |
|
|
0000110 |
|
|
& |
|
0000100 |
(4) |
и |
& 0000001 |
(1) |
|
|
0000100 |
(4) |
|
|
0000000 |
(0) |
Обычно операция & используется для двух целей: проверить наличие битов или убрать { т.е. обнулить) некоторые из них. Например, надо проверить состояние бита номер 5 (нумерация идет справа налево, от 0 до 7). Единица в бите 5 дает число 2 - 32. Это второй аргумент. Если в А в пятом бите есть единица, то должно выполниться усло-
âèå ( A & 32 ) = 32. Осталось оформить все это в оператор IF. Можно проверить наличие сразу нескольких «включенных» битов, например, 5-го, 2-го и 0-го. Число с единицами в этих позициях и нулями в остальных равно 2 + 2 + 1 = 32+4+1 = 37. Если А среди прочих имеет единицы в битах 5, 2 и 0, то в этом случае будет истинным выражение
( A & 37 ) = 37
Исключение или выключение битов достигается следующим образом. Пусть надо исключить бит 3 из переменной А типа Char. Исключить — значит, задать нулем. Первым делом определяется число, в котором все биты равны 1, кроме бита номер 3. Для типа Char оно равно (255 - 23 = 247, где 255 — максимальное значение вписываемое в байт. Если теперь это число логически умножить на А, то единицы в 247 никак не повлияют на состояние битов в переменной А, а ноль в третьем бите заместит любое значение в А на том же месте. Таким образом, можно записать А = A & (255 - 8); чтобы получить значение А с отключенным 3-м битом.
| поразрядная дизъюнкция (ИЛИ) битовых представлений целочисленных операндов; определяется следующими действиями над битами:
[1] | [0] = [0] | [1] = [1]
[0]| [0] = [0]
[1]| [1] = [1]
Квадратные скобки обозначают один бит. Эта операция может с успехом применяться при включении (установки в 1) отдельных битов двоичного представления целых чисел. Так, если надо, чтобы бит 4 значения А стал равным единице, а остальные не изменились, то следует записать
А = A | 16;
Аналогичным образом можно включать сразу несколько битов, например, 4-й, 1-й и 0-й:
А= A | (16 + 2 + 1);
^поразрядное исключающее ИЛИ битовых представлений целочисленных операндов; (математическое название — «сложение по модулю 2»). Эта операция возвращает 0, когда оба ее аргумента равны, и 1 в противном слу- чае:
[1] ^ [1] = [0]
[0]^ [0] = [0]
[1]^ [0] = [0] ^ [1] = [1]
Операцию ^ можно с успехом применять при смене значения бита (или нескольких битов) на противоположные. Пусть необходимо переключить состояние бита 5 числа А. Это будет сделано операцией А ^ 32 , где 32 = 25.
Исключающее 'ИЛИ' обладает одной особенностью: примененное дважды к одной и той же переменной, оно восстановит ее исходное значение, т.е. всегда выполняется равенство:
А = ( А ^ В ) ^ В
Операции сдвигов » (вправо) и « (влево) должны иметь целочисленные операнды. Над битовым представлением значения левого операнда выполняется действие - сдвиг. Правый операнд определяет величину поразрядного сдвига.
При сдвиге влево на N позиций двоичное представление левого операнда сдвигается, а освобождающиеся слева разряды заполняются нулями. Такой сдвиг эквивалентен умножению значения операнда на 2N .
Сдвиг вправо на N позиций несколько сложнее. Тут следует отметить две особенности, Первое - это исчезновение младших разрядов, выходящих за разрядную сетку. Вторая особенность -отсутствие стандарта на правило заполнения освобождающихся левых разрядов. В стандарте языка сказано, что когда левый операнд есть целое значение с отрицательным знаком, то при сдвиге вправо заполнение освобождающихся левых разрядов определяется реализацией. Здесь возможны два варианта: освобождающиеся разряды заполняются значениями знакового разряда (арифметический сдвиг вправо) или освобождающиеся слева разряды заполняются нулями (логический сдвиг вправо).
При положительном левом операнде сдвиг вправо на N позиций эквивалентен уменьшению значения левого операнда в 2N раз с отбрасыванием дробной части результата. (Поэтому 5>>2 равно 1.)
Например, число с двоичным представлением 11011011 будет трансформироваться при сдвигах влево следующим образом:
( 11011011 |
<< 0 ) = 11011011 |
|
( 11011011 |
<< 1 ) = 10110110 |
|
( 11011011 |
<< 2 ) = 01101100 |
|
( 11011011 |
<< 3 |
) = 11011000 |
( 11011011 |
<< 4 |
) = 10110000 |
( 11011011 |
<< 7 |
) = 10000000 |
( 11011011 |
<< 8 |
) = 00000000 |
++- увеличение на единицу (инкремент или автоувеличение) как и
--- уменьшение на единицу (декремент или автоуменьшение) ; имеет две формы:
префиксная операция - увеличение значения операнда на 1 до его использования. Ассоциативность справа в соответствии со стандартом;
постфиксная операция - увеличение значения операнда на 1 после его использования. Ассоциативность слева в
Лысый Д.А. Лекция(продолжение) Операции в Си |
3 |
соответствии со стандартом.
Операндами унарных операций ++ и — должны быть всегда модифицируемые именующие выражения (L-value, left value, /-значение, леводопустимое выражение). Термины "леводопустимое выражение" и "l-значение" происходят от объяснения действия операции присваивания Е = D, в которой операнд Е слева от знака операции присваивания может быть только модифицируемым l-значением. Примером модифицируемого /-значения служит имя переменной, которой выделена память. Таким образом, /-значение - ссылка на область памяти, значение которой доступно изменениям;
выражение ++n увеличивает на 1 значение n, и это полученное значение используется как значение выражения ++n (префиксная форма);
выражение —k уменьшает на 1 значение k, и это новое значение используется как значение выражения --k (префиксная форма);
выражение i++ (постфиксная форма) увеличивает на 1 значение i, однако значением выражения i++ является предыдущее значение i (до его увеличения);
выражение j— (постфиксная форма) уменьшает на 1 значение j, однако значением выражения j— является предыдущее значение j (до его уменьшения).
Например, если n равно 4, то при вычислении выражения n++*2 результат равен 8, а n примет значение 5. При n, равном 4, значением выражения ++n*2 будет 10, а n станет равно 5.
Условная трехместная операция. В отличие от унарных и бинарных операций условная тернарная операция используется с тремя операндами:
выражение_1 ? выражение_ 2: выражение _3
Первым вычисляется значение выражения_1. Если оно истинно, т.е. не равно нулю, то вычисляется значение выражения_2, которое становится результатом. Если при вычислении выражения_1 получится 0, то в качестве результата берется значение выражения_3. Пример:
х < 0 ? -х : х; Выражение возвращает абсолютную величину переменной х.
sizeof - операция вычисления размера (в байтах) для объекта того типа, который имеет операнд. Разрешены два формата операции: sizeof выражение sizeof(mun).
sizeof не вычисляет значения выражения, а только определяет его тип, для которого затем вычисляется размер.
Пример: для определения количества элементов в массиве A[4] можнл использовать следующее выражение - sizeof (A)/ sizeof(A[0])
Запятая в качестве операции:
, несколько выражений, разделенных запятыми, вычисляются последовательно слева направо. В качестве результата сохраняются тип и значение самого правого выражения.
#include <stdio.h> main(){
double i=10., j=20.,k; k=(i++,k=0,k=i*3)+j; printf("\n%lf",k);
}
Резóльтат k=53.0