Программная инженерия. 1 курс 1 семестр / Лекции / L-05.Operatoriinstrykciiivirajeniya
.pdfСПбГУТ им. проф. М.А. Бонч–Бруевича Кафедра программной инженерии и вычислительной техники (ПИ и ВТ)
ПРОГРАММИРОВАНИЕ
Единственный способ изучать новый язык программирования – писать на нем программы.
Брайэн Керниган
Лекция 5: Операции, инструкции и выражения
1.Операции
2.Операторы
3.Выражения
4.Приведение типов в выражениях
Санкт–Петербург, 2021г.
1. Обработка данных. Операции
Существует целый слой выразительных средств языка –
средства обработки данных.
Это – набор элементарных действий (операций) и их сочетаний (выражений), который позволяет изменять значения переменных.
К ним относятся:
традиционные операции над переменными
(например, арифметические, логические, поразрядные);
присваивание;
ввод-вывод;
вызов процедур и функций.
Для начала – немного терминологии:
Операция – элементарное действие по обработке данных (по работе с переменными);
Операнд – переменная, константа, выражение, участвующие в операции;
Унарная операция – операция с одним операндом;
Бинарная операция – операция с двумя операндами;
Выражение – элемент синтаксиса с описанием последовательности выполнения операций и их операндов, в котором результат одной операции является операндом другой.
Особенности операций в Си:
их многочисленность;
к операциям относятся такие действия, которые в других языках программирования считаются операторами (например, присваивание);
все они имеют очень «компактный» синтаксис, т.е. при пропуске или добавлении лишнего символа одна операция превращается в другую.
Все это требует внимательного и осознанного отношения к
операциям в Си.
Перечислим их особенности:
операции разбиты на 16 групп по приоритетам их выполнения;
внутри каждой группы задается направление выполнения операции для последовательности операций одного приоритета. Для большинства из них имеет место естественное направление слева направо. Однако для операций присваивания, условной операции и унарных операций, у которых знак (символ) операции находится перед операндом (слева), направление операций противоположное - справа налево;
большинство операций совместимо по результатам. Это значит, что результат любой операции может быть операндом любой другой операции, то есть их можно комбинировать между собой как угодно, даже в самых «диких» сочетаниях;
в Си отсутствует понятие логического (булевого) типа «истиналожь»;
в некоторых операциях возможно изменение значений участвующих в ней операндов;
Программа:
Операторы; …;
Выражения…
Операнды, Операции, Скобки…
Переменные, Константы, Выражения
2
Обработка данных. Операции
Выражения используются для вычисления значений (определенного типа) и состоят из операндов, операций и скобок. Каждый операнд может быть, в свою очередь, выражением или одним из его частных случаев – константой или переменной. Операнды задают данные для вычислений.
Знак операции – это один или |
Классификация операций |
||
более символов, определяющих |
по количеству |
||
действие над операндами, т.е. |
участвующих в них |
||
операции |
задают |
действия, |
операндов |
которые необходимо выполнить. |
|
||
|
Внутри знака операции пробелы не допускаются.
унарные бинарные тернарные
Операции выполняются в соответствии с приоритетами. Для изменения порядка выполнения операций используются круглые скобки.
Большинство операций |
|
Исключение |
составляют |
унарные |
|
выполняются слева направо, |
|
операции, операции присваивания и |
|||
например, a+b+c (a+b)+c. |
|
условная |
операция |
(?:), |
которые |
|
|
выполняются справа налево. |
|
||
|
|
||||
|
|
|
|
|
|
3
Операции (15 рангов)
Знаки операций
Для формирования и последующего вычисления выражений используются операции.
Для изображения одной операции в большинстве случаев используется несколько символов.
В табл. справа приведены все знаки операций, определенные стандартом языка.
Операции в таблице разбиты на группы в соответствии с их
рангами.
За исключением операций "[ ]", "( )" и "?:", все знаки операций распознаются компилятором как отдельные лексемы.
В зависимости от контекста одна и та же лексема может обозначать разные операции, то есть один и тот же знак операции может употребляться в различных выражениях и по– разному интерпретироваться в зависимости от контекста.
Например,
бинарная операция & – это поразрядная конъюнкция,
унарная операция & – это операция получения адреса.
Операции ранга 1 имеют наивысший приоритет.
Операции одного ранга имеют одинаковый приоритет, и если их в выражении несколько, то они выполняются в соответствии с правилом ассоциативности либо слева направо (→), либо справа налево (←).
Если один и тот же знак операции приведен в таблице дважды (например, знак *), то первое появление (с меньшим по номеру, то есть старшим по приоритету, рангом) соответствует унарной операции, а второе – бинарной.
Арифметические выражения в языке Си играют существенно более важную роль, чем в Паскале:
в Си присутствует такая нетривиальная вещь, как
адресная арифметика ;
привычное присваивание, которое в Паскале было оператором, в Си совершенно неожиданно оказывается операцией и может, как следствие, быть частью арифметического выражения.
особенность Си — операция присваивания, а не оператор присваивания, как в большинстве языков программирования представляет собой выражение, и это выражение имеет значение
— оно равно тому значению, которое было только что присвоено, то есть занесено в переменную слева от присваивания:
x = (y = 17) + 1; |
// допустимо в Си |
a = b = c = d = e + 5; |
4 |
Обзор операций
В языке Си используются четыре унарные операции, имеющие самый высокий приоритет, их часто называют первичными.
Первичные операции
Операция доступа к полям структур и объединений при помощи идентификаторов «.» – точка
Операция доступа к полям структур и объединений при помощи указателей «–>» – стрелка
Операция [ ] индексации, используемая при декларации массива и обращении к его элементам
Операция ( ) обращения к функции
Арифметические операции
Обозначения арифметических операций
+ |
|
сложение |
|
- |
|
|
вычитание |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/ |
|
деление |
|
* |
|
|
умножение |
|
|
|
|
|
|
|
|
|
|
%остаток от деления целочисленных операндов со знаком первого операнда
– деление «по модулю»
Деление, для int операндов происходит с отбрасыванием остатка
Операндами традиционных арифметических операций
(+ – * /) могут быть константы, переменные, обращения к возвращающим значения функциям, элементы массивов,
любые |
арифметические |
выражения, |
указатели |
(с |
|||
ограничениями) |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Порядок выполнения действий в |
|
|
|
|
|
|
|
арифметических выражениях |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Выражения в круглых скобках |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
операции * , / , % |
|
|
|
|
|
|
|
|
|
|
|
|
|
операции + , –
Операции * , / , % обладают высшим приоритетом над операциями +, – , поэтому при записи сложных выражений нужно использовать общепринятые математические правила - использовать круглые скобки.
a |
x+y*z–a /(b+с) |
x y z b c |
5
Унарные (одноместные) операции
Для изображения одноместных префиксных и постфиксных операций используются следующие символы:
& операция получения адреса операнда (ранг 2);
* операция обращения по адресу, то есть раскрытия ссылки,
иначе операция разыменования (доступа по адресу к значению того объекта, на который указывает операнд). Операндом должен быть указатель (ранг 2);
– (унарный минус), изменяет знак арифметического операнда
(ранг 2);
+ (унарный плюс), введен для симметрии с унарным минусом
(ранг 2);
поразрядное инвертирование внутреннего двоичного кода целочисленного аргумента – побитовое отрицание (ранг 2);
! логическое отрицание (НЕ) значения операнда (ранг 2).
Применяется к скалярным операндам. Целочисленный результат 0 (если операнд ненулевой, то есть истинный) или 1 (если операнд нулевой, то есть ложный).
Таким образом: !1 равно 0; !2 равно 0; !(–5) равно 0; !0 равно 1;
++ увеличение на единицу (инкремент или автоувеличение – ранг 2); имеет две формы:
префиксная операция – увеличение значения операнда на 1 до его использования. Ассоциативность справа в соответствии со стандартом;
постфиксная операция – увеличение значения операнда на 1 после его использования. Ассоциативность слева в соответствии со стандартом.
Операнд для операции ++ (и для операции --) не может быть константой либо произвольным выражением.
Записи ++5 или 84++ будут неверными.
++(j+k) - также неверная запись.
Операндами унарных операций ++ и -- должны быть всегда модифицируемые именующие выражения (L-value, left value, l- значение, леводопустимое выражение).
Термины «леводопустимое выражение» и «l-значение» происходят от объяснения действия операции присваивания E = D, в которой операнд E слева от знака операции присваивания может быть только модифицируемым l-значением.
Примером модифицируемого l-значения служит имя переменной, которой выделена память.
Таким образом, l -значение – ссылка на область памяти, значение которой доступно изменениям;
-- уменьшение на единицу (декремент или автоуменьшение - ранг 2) - унарная операция, операндом которой должно быть леводопустимое выражение, то есть не константа и не выражение:
префиксная операция - уменьшение на 1 значения операнда до его использования;
постфиксная операция - уменьшение на 1 значения операнда после его использования;
sizeof операция (ранг 2) вычисления размера (в байтах) для объекта того типа, который имеет операнд. Разрешены два формата операции:
sizeof выражение;
sizeof (тип);
sizeof не вычисляет значения выражения, а только определяет его тип, для которого затем вычисляется размер.
6
Бинарные (двуместные) операции
Делятся на следующие группы:
аддитивные;
мультипликативные;
сдвигов;
поразрядные;
операции отношений;
логические;
присваивания;
выбора компонента структурированного объекта;
операция «запятая»;
скобки в качестве операций.
Аддитивные операции:
+ бинарный плюс - сложение арифметических операндов или сложение указателя с целочисленным операндом (ранг 4);
– бинарный минус - вычитание арифметических операндов или вычитание указателей (ранг 4).
Мультипликативные операции:
* умножение операндов арифметического типа (ранг 3);
/ деление операндов арифметического типа (ранг 3).
При целочисленных операндах абсолютное значение результата округляется до целого.
Например, 20/3 равно 6; -20/3 равно -6; (-20)/3 равно -6;
20/(-3) равно -6;
% получение остатка от деления целочисленных операндов
(деление по модулю - ранг 3). При неотрицательных операндах остаток положительный. В противном случае остаток определяется реализацией.
Например:
13%4 = 1, (-13)%4 = -1; 13%(-4) = +1, а (-13)%(-4) = -1.
При ненулевом делителе для целочисленных операндов всегда выполняется соотношение:
(a/b)*b + a%b = a.
Операции сдвига:
Операции сдвига (определены только для целочисленных операндов). Формат выражения с операцией сдвига:
операнд_левый операция_сдвига операнд_правый
<< сдвиг влево битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого целочисленного операнда (ранг 5);
>> сдвиг вправо битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого целочисленного операнда (ранг 5).
Поразрядные операции (на битовом уровне):
& поразрядная конъюнкция (И) битовых представлений значений целочисленных операндов (ранг 8);
| поразрядная дизъюнкция (ИЛИ) битовых представлений значений целочисленных операндов (ранг 10);
^ поразрядное исключающее ИЛИ битовых представлений
значений целочисленных операндов (ранг 9). Результат выполнения операций сдвига и поразрядных
операций:
4<<2 = 16; Напомню, что двоичный код для 4 равен 100, для 5 - это 101, для 6 - это 110 и т. д. При сдвиге влево на две позиции код 100 становится
5>>1 = 2; |
равным 10000 (десятичное значение равно 16). Остальные |
|
результаты операций сдвига и поразрядных операций могут быть |
||
6&5 = 4; |
прослежены аналогично. |
|
6 | 5 = 7; |
|
|
Обратите внимание, что сдвиг влево на n позиций эквивалентен |
|
|
6^5 = 3. |
умножению значения на 2n, а сдвиг кода вправо уменьшает |
|
|
соответствующее значение в 2n раз с отбрасыванием дробной |
7 |
|
части результата. (Поэтому 5>>1 равно 2.) |
Бинарные (двуместные) операции
Операции отношений (сравнения):
< меньше, чем (ранг 6);
> больше, чем (ранг 6);
<= меньше или равно (ранг 6);
>= больше или равно (ранг 6);
== равно (ранг 7);
!= не равно (ранг 7).
Операнды операций отношений должны быть
арифметического типа или могут быть указателями.
Результат целочисленный: 0 (ложь) или 1 (истина).
Последние две операции (операции сравнения на равенство) имеют более низкий приоритет по сравнению с остальными операциями отношений.
Таким образом, выражение (x < B == A < x) есть 1 тогда и только тогда, когда значение x находится в интервале от A до B и A<B. (Вначале вычисляются x < B и A < x, а к результатам применяется операция сравнения на равенство ==.)
Логические бинарные операции:
&& конъюнкция (И) арифметических операндов или отношений (ранг 11). Целочисленный результат 0 (ложь) или
1(истина);
|| дизъюнкция (ИЛИ) арифметических операндов или отношений (ранг 12). Целочисленный результат 0 (ложь) или
1(истина).
(Вспомним о существовании унарной операции отрицания '!'.)
Результаты отношений и логических операций:
3<5 = 1; 3>5 = 0;
3==5 равняется 0; 3!=5 равняется 1;
3!=5 || 3==5 равняется 1; 3+4>5 && 3+5>4 && 4+5>3 равняется 1.
Операции присваивания (ранг 14):
В качестве левого операнда в операциях присваивания может использоваться только модифицируемое именующее выражение (L-значение), то есть ссылка на некоторую именованную область памяти, значение которой доступно изменениям.
Перечислим операции присваивания, отметив, что существуют одна простая операция присваивания и ряд составных операций:
= простое присваивание: присвоить значение выраженияоперанда из правой части операнду левой части.
Пример: P = = 10.3 - 2*x;
*= присваивание после умножения: присвоить операнду левой части произведение значений обоих операндов.
P *= 2 эквивалентно P = P * 2;
/= присваивание после деления: присвоить операнду левой ча-
сти частное от деления значения левого операнда на значение правого.
P /= 2.2 - d эквивалентно P = P / (2.2 - d);
%= присваивание после деления по модулю: присвоить операнду левой части остаток от целочисленного деления значения левого операнда на значение правого операнда.
N %= 3 эквивалентно N = N % 3;
8
Операции
Операции сравнения в языке Си
== |
|
равно или эквивалентно |
|
!= |
|
не равно |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
< |
|
меньше |
|
|
|
меньше либо равно |
|
|
<= |
|
|||
|
|
|
|
|
|
|
> |
|
больше |
|
>= |
|
больше либо равно |
|
|
|
|
|
|
|
Общий вид операций отношений
Операнд_1 Знак операции Операнд_2
В языке Си нет логического типа данных.
Результат операции отношения имеет значение 1, если отношение истинно (true), или 0 – в противном случае, т.е. – ложно (false).
Следовательно, операция отношения может использоваться в любых арифметических выражениях.
Указанные операции выполняют сравнение значений первого операнда со вторым.
Операндами могут быть любые арифметические выражения
и указатели.
Значения арифметических выражений перед сравнением
вычисляются и преобразуются к одному типу
Пример:
y > 0 , x == y , x != 2
|
|
|
|
Логические операции |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Логические операции в порядке |
|
|
|
|
|
|
убывания относительного |
|
|
|
|
|
|
приоритета |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
! |
|
|
отрицание (логическое «НЕТ», “NOT”) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&& |
|
|
конъюнкция (логическое «И», “AND”) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|| |
|
|
дизъюнкция (логическое «ИЛИ», “OR”) |
|
|
|
|
|
|
|
|
|
Операндами (выражениями) логических операций могут быть любые скалярные типы.
Ненулевое значение операнда трактуется как «истина», а нулевое – «ложь».
Результатом логической операции, как и в случае операций отношения, может быть 1 или 0.
Операция отрицания: |
Общий вид операции отрицания: |
|
!0 |
1 |
! выражение |
!5 |
0 |
|
x = 10;
! (x > 0) 0
9
Бинарные (двуместные) операции
Операции присваивания (ранг 14, продолжение):
+= присваивание после суммирования: присвоить операнду левой части сумму значений обоих операндов.
A += B эквивалентно A = A + B;
-= присваивание после вычитания: присвоить операнду левой части разность значений левого и правого операндов.
X -= 4.3 - Z эквивалентно X = X - (4.3 - Z);
<<= присваивание после сдвигов разрядов влево: присвоить целочисленному операнду левой части значение, полученное сдвигом влево его битового представления на количество разрядов, равное значению правого целочисленного операнда.
Например, a <<= 4 эквивалентно a = a << 4;
>>= присваивание после сдвигов разрядов вправо:
присвоить целочисленному операнду левой части значение, полученное сдвигом вправо его битового представления на количество разрядов, равное значению правого целочисленного операнда.
Например, a >>= 4 эквивалентно a = a >> 4;
&= присваивание после поразрядной конъюнкции:
присвоить целочисленному операнду левой части значение, полученное поразрядной конъюнкцией (И) его битового
представления с битовым представлением целочисленного операнда правой части.
e &= 44 эквивалентно e = e & 44;
|= присваивание после поразрядной дизъюнкции:
присвоить целочисленному операнду левой части значение, полученное поразрядной дизъюнкцией (ИЛИ) его битового представления с битовым представлением целочисленного операнда правой части.
a |= b эквивалентно a = a | b;
^= присваивание после исключающего поразрядного «ИЛИ»:
присвоить целочисленному операнду левой части значение, полученное применением поразрядной операции исключающего ИЛИ к битовым представлениям значений обоих операндов.
z ^= x + у эквивалентно z = z ^ (x + y)
Обратите внимание, что для всех составных операций присваивания форма присваивания E1 op= E2 эквивалентна E1 = E1 op (E2), где op - обозначение операции.
Операции выбора компонентов структурированного объекта:
. (точка) - прямой выбор (выделение) компонента структурированного объекта, например объединения или структуры
(ранг 1).
Формат применения операции:
имя_структурированного_объекта . имя_компонента
-> - косвенный выбор (выделение) компонента структури-
рованного объекта, адресуемого указателем (ранг 1).
При использовании операции требуется, чтобы с объектом был связан указатель (указателям посвящена отдельная тема).
В этом случае формат применения операции имеет вид:
указатель_на_структурированный_объект -> имя_компонента
Так как операции выбора компонентов структурированных объектов используются со структурами и объединениями, то необходимые пояснения и примеры приведем позже, введя перечисленные понятия и, кроме того, аккуратно определив указатели.
10