книги / Программирование на языке Си
..pdf32 |
Программирование на языке Си |
В заголовочном файле float.li находятся директивы, опреде ляющие константы, связанные с представлением данных веще ственных типов. Например:
#define EXT_MIN 1.17549435E-38F
♦define DBL_MIN 2.2250738585072014E-308 ♦define DHL_EPSIL<PN 2 .2204460492503131E-16
Значения этих предопределенных на препроцессорном уров не констант в соответствии со стандартом языка в конкретных компиляторах могут быть несколько иными, отличными от тех, что приведены в-таблицах Приложения 2.
Подробно о возможностях прелроцессорных средств будет говориться в главе 3. Сейчас достаточно знать, что, записав в тексте своей программы директиву
♦include <limits.h>
можно использовать в программе стандартные именованные константы CHAR BIT, SHRT MLN и т.д. (см. Приложение 2), а уж их значениямиебудут те числа, которые включили в дирек тивы #define авторы конкретного компилятора и конкретной библиотеки.
Если включить в программу директиву
♦include <float.h>
то станут доступными именованные константы предельных значений числовых даннь(х вещественных типов (см. Прило жение 2).
Такой подход к определению предельных значений с помо щью препроцессорных констант, сохраняемых в библиотечных файлах; позволяет писать программы, не зависящие от реализа ции, что обеспечивает их достаточную мобильность. Програм мист использует в программе стандартные имена (обозначе ния) констант, а их значения определяются версией реализации, т.е. конкретным компилятором и его библиотеками.
Глава 1. Базовые понятия языка |
33 |
1.4.О перации
Вэтом параграфе достаточно лаконично определяются все операции языка Си и приводится таблица их приоритетов. Хотя
вближайших параграфах (где вводятся выражения и основные операторы языка) нам понадобятся не все знаки операций и не редко будет достаточно интуитивного представления об их старшинстве и ассоциативности, но материал этого параграфа слишком важен, чтобы говорить о нем позже. В последующих главах применение операций языка будет рассмотрено подроб но, но к таблице приоритетов стоит обращаться и при дальней шем чтении, и при написании программ.
Знаки операций. Для формирования и последующего вы числения выражений используются операции. Для изображения одной операций в большинстве случаев используется несколько символов. В табл. 1.4 приведены все знаки операций, опреде ленные стандартом языка. Операции в таблице разбиты на
группы в соответствии с их рангами. |
|
За исключением операций "[]", "()" и |
все знаки опера |
ций распознаются компилятором как отдельные лексемы. В за висимости от контекста одна и та же лексема может обозначать разные операции, т.е. один и тот же знак операции может упот ребляться в различных выражениях и по-разному интерпретиро ваться в зависимости от контекста. Например, бинарная опера ция & - это поразрядная конъюнкция, а унарная операция & - это операция получения адреса.
Операции ранга 1 имеют наивысший приоритет. Операции одного ранга имеют одинаковый приоритет, и если их в выра жении несколько, то они выполняются в соответствии с прави лом ассоциативности либо слева направо (->), либо справа налево (4-). Если один и тот же знак операции приведен в таб лице дважды (например, знак *), то первое появление (с мень шим по номеру, т.е. старшим по приоритету, рангом) соответствует унарной операции, а второе - бинарной.
Опишем кратко возможности отдельных операций.
3 -3 1 2 4
34 |
|
|
|
|
|
Программирование на языке Си |
|||
|
|
|
|
|
|
|
|
Таблица |
1.4 |
|
|
|
Приоритеты (ранги) операций |
|
|
|
|||
Ранг |
|
|
|
|
Операции |
|
Ассоциа |
||
|
|
|
|
|
|
|
|
тивность |
|
1 |
о |
и |
|
-> |
• |
|
|
-> |
|
2 |
! |
- |
+ |
- + + |
— & * ( т и п ) |
sizeof |
<— |
|
|
3 |
* |
/ |
% |
(мультипликативные бинарные) |
-> |
|
|||
4 |
+ |
- |
(аддитивные бинарные) |
|
-> |
|
|||
5 |
« |
» |
(поразрядного сдвига) |
|
-> |
|
|||
6 |
< |
< |
- > |
= |
> |
(отношения) |
|
-> |
|
7 |
= |
|
!= |
(отношения) |
|
-> |
|
||
8 |
& |
(поразрядная конъюнкция "И") |
|
-> |
- |
||||
9 |
Л |
(поразрядное исключающее "ИЛИ") |
|
-> |
|
||||
10 |
| |
(поразрядная дизъюнкция "ИЛИ") |
|
-» |
|
||||
11 |
&& |
(конъюнкция "И") |
|
-> |
|
||||
12 |
|| |
(дизъюнкция "ИЛИ”) |
|
-» |
|
||||
13 |
?: |
(условная операция) |
|
<— |
|
||||
14 |
= |
*= |
/= |
%= |
+= |
-= &= л= |= « = |
» = |
<— |
|
15 |
, |
(операция "запятая") |
|
-> |
|
Унарные (одноместные) операции. Для изображения од номестных префиксных и постфиксных операций используются следующие символы:
&- операция получения адреса операнда (ранг 2);
*- операция обращения по адресу, т.е. раскрытия ссыл ки, иначе операция разыменования (доступа по ад ресу к значению того объекта, на который указывает операнд). Операндом должен быть указатель (ранг
2) ;
-унарный минус, изменяет знак арифметического операнда (ранг 2);
Глава 1. Базовые понятия языка |
35 |
+- унарный плюс, введен для симметрии с унарным
минусом (ранг 2);
~- поразрядное инвертирование внутреннего двоичного кода целочисленного аргумента - побитовое отрица
ние (ранг 2);
!- НЕ - логическое отрицание значения операнда (ранг 2). Применяется к скалярным операндам. Целочис ленный результат 0 (если операнд ненулевой, т.е. истинный) или 1 (если операнд нулевой, т.е. лож ный). Напомним, что в качестве логических значе ний в языке используют целые числа: 0 - ложь и не нуль, т.е. (!0) - истина. Отрицанием любого ненуле вого числа будет 0, а отрицанием нуля будет 1. Та ким образом: !1 равно 0; 12 равно 0; !(-5) равно 0; !0 равно 1;
++- увеличение на единицу (инкремент или автоувеличе ние - ранг 2); имеет две формы:
префиксная операция - увеличение значения опе ранда на 1 до его использования. Ассоциативность справа в соответствии со стандартом;
постфиксная операция - увеличение значения операнда на 1 после его использования. Ассоциатив ность слева в соответствии со стандартом.
Операнд для операции ++ (и для операции — ) не может быть константой либо произвольным выраже нием. Записи ++5 или 84++ будут неверными. ++(j+k) также неверная запись. Операндами унарных опера ций ++ и — должны быть всегда модифицируемые именующие выражения (L-value, left value, I-зна чение, леводопустимое выражение). Термины "лево допустимое выражение" и "/-значение" происходят от объяснения действия операции присваивания Е = D, в которой операнд Е слева от знака операции при сваивания может быть только модифицируемым /- значением. Примером модифицируемого /-значения служит имя переменной, которой выделена память^
3*
36 |
Программирование на языке Си |
Таким образом, /-значение - ссылка на область памя ти, значение которой доступно изменениям;
-уменьшение на единицу (декремент или автоумень шение - ранг 7) - унарная операция, операндом ко торой должно быть леводопустимое выражение, т.е. не константа и не выражение:
префиксная операция - уменьшение на 1 значения операнда до его использования;
постфиксная операция - уменьшение на 1 значе
ния операнда после его использования;
sizeof - операция (ранг 2) вычисления размера (в байтах) для объекта того типа, который имеет операнд. Разреше ны два формата операции:
sizeof выражение sizeoi(mun).
sizeof не вычисляет значения выражения, а только определяет его тип, для которого затем вычисляется размер.
Бинарные (двуместные) операции делятся на следующие группы:
•аддитивные;
•мультипликативные;
•сдвигов;
•поразрядные;
•операции отношений;
•логические;
•присваивания;
•выбора компонента структурированного объекта;
•операция "запятая";
•скобки в качестве операций.
Аддитивные операции:
+- бинарный плюс - сложение арифметических операндов или сложение указателя с целочисленным операндом
(ранг 4);
-- бинарный минус - вычитание арифметических операн дов или вычитание указателей (ранг 4).
Глава 1. Базовые понятия языка |
37 |
Мультипликативные операции:
* - умножение операндов арифметического типа (ранг 3);
/- деление операндов арифметического типа (ранг 3). При целочисленных операндах абсолютное значение результата округляется до целого. Например, 20/3 рав но 6, -20/3 равно -6, (-20)/3 равно -6, 20/(-3) равно -6;
%- получение остатка от деления целочисленных операн дов (деление по модулю - ранг 3). При неотрицатель ных операндах остаток положительный. В противном случае остаток определяется реализацией. В компиля торе Turbo С:
13%4 равняется 1, (—13)%4 равняется -1;
13%(—4) равно +1, а (-13)%(-4) равняется -1.
При ненулевом делителе для целочисленных операн дов всегда выполняется соотношение: (a/b)*b + а%Ь равно а.
Операции сдвига (определены только для целочисленных операндов). Формат выражения с операцией сдвига:
операнд левый операция сдвига операнд правый
«- сдвиг влево битового представления значения левого целочисленного операнда на количество разрядов, рав
ное значению правого целочисленного операнда
(ранг 5);
»- сдвиг вправо битового представления значения левого целочисленного операнда на количество разрядов, рав
ное значению правого целочисленного операнда
(ранг 5).
Поразрядные операции:
&- поразрядная конъюнкция (И) битовых представлений значений целочисленных операндов (ранг 8);
I- поразрядная дизъюнкция (ИЛИ) битовых представле ний значений целочисленных операндов (ранг 10);
А- поразрядное исключающее ИЛИ битовых представле ний значений целочисленных операндов (ранг 9).
38 |
|
Программирование на языке Си |
Результат выполнения операций сдвига и поразрядных one |
||
раций: |
равняется 16; |
|
4 « 2 |
||
5 » 1 |
равняется |
2; |
6&5 |
равняется |
4; |
6 15 |
равняется' |
7; |
6-5 |
равняется |
3. |
Напоминаем, что двоичный код для 4 равен 100, для 5 - это 101, для 6 - это 110 и т.д. При сдвиге влево на две позиции код 100 становится равным 10000 (десятичное значение равно 16). Остальные результаты операций сдвига и поразрядных опера ций могут быть прослежены аналогично.
Обратите внимание, что сдвиг влево на п позиций эквивален тен умножению значения на 2", а сдвиг кода вправо уменьшает соответствующее значение в 2" раз с отбрасыванием дробной части результата. (Поэтому 5 » 1 равно 2.)
Операции отношений (сравнения):
<меньше, чем (ранг б);
>больше, чем (ранг б);
<= меньше или равно (ранг б); >= больше или равно (ранг б);
—равно (ранг 7);
!= не равно (ранг 7).
Операнды операций отношений должны быть арифметиче ского типа или могут быть указателями. Результат целочислен ный: 0 (ложь) или 1 (истина). Последние две операции (операции сравнения на равенство) имеют более низкий при оритет по сравнению с остальными операциями отношений. Та ким образом, выражение (х < В — А < х) есть 1, когда значение х находится в интервале от А до В и А<В либо х, А, В равны. (Вначале вычисляются х < В и А < х , а к результатам применя ется операция сравнения на равенство — .)
Логические бинарные операции:
&&- конъюнкция (И) арифметических операндов или от ношений (ранг 11). Целочисленный результат 0 (ложь) или 1 (истина);
Глава 1. Базовые понятия языка |
39 |
I I - дизъюнкция (ИЛИ) арифметических операндов |
или |
отношений (ранг 12). Целочисленный результат О (ложь) или 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)
В качестве левого операнда в операциях присваивания может использоваться только модифицируемое именующее выраже ние (/-значение), т.е. ссылка на некоторую именованную об ласть памяти, значение которой доступно изменениям.
Перечислим операции присваивания, отметив, что сущест вуют одна простая операция присваивания и ряд составных опе раций:
=- простое присваивание: присвоить значение выраже ния-операнда из правой части операнду левой части. Пример: Р = 10.3 - 2*х;
*= |
присваивание после умножения: присвоить операнду |
|
левой части произведение значений обоих операндов. |
|
Р *= 2 эквивалентно Р = Р * 2; |
/= |
- присваивание после деления: присвоить операнду ле |
|
вой части частное от деления значения левого опе |
|
ранда на значение правого. Р /= 2.2 - d эквивалентно |
Р = Р / (2.2 - d);
%= - присваивание после деления по модулю: присвоить операнду левой части остаток от целочисленного де ления значения левого операнда на значение правого операнда. N %= 3 эквивалентно N = N % 3;
+= - присваивание после суммирования: присвоить опе ранду левой части сумму значений обоих операндов А += В эквивалентно А = А + В;
40 |
|
|
|
|
Программирование на языке Си |
-= |
- |
присваивание после вычитания: присвоить операнду |
|||
|
|
левой части разность значений левого и правого опе |
|||
|
|
рандов. X -= 4.3 - Z эквивалентно X = X - (4.3 - Z); |
|||
« = |
- |
присваивание после сдвигов разрядов влево: присво |
|||
|
|
ить целочисленному операнду левой части значение, |
|||
|
|
полученное сдвигом влево его битового представле |
|||
|
|
ния на количество разрядов, равное значению пра |
|||
|
|
вого |
целочисленного |
операнда. Например, а « = 4 |
|
|
|
эквивалентно а = а « |
4; |
||
» = |
- |
присваивание после сдвигов разрядов вправо: присво |
|||
|
|
ить целочисленному операнду левой части значение, |
|||
|
|
полученное сдвигом вправо его битового представле |
|||
|
|
ния на количество разрядов, равное значению пра |
|||
|
|
вого |
целочисленного |
операнда. Например, а » = 4 |
|
|
|
эквивалентно а = а » |
4; |
||
&= |
- |
присваивание после поразрядной конъюнкции: при |
|||
|
|
своить целочисленному операнду левой части значе |
|||
|
|
ние, полученное поразрядной конъюнкцией (И) его |
|||
|
|
битового представления с битовым представлением |
|||
|
|
целочисленного операнда правой части е &= 44 экви |
|||
|
|
валентно е = е & 44; |
|
||
1= |
- |
присваивание после поразрядной дизъюнкции: при |
|||
|
|
своить целочисленному операнду левой части значе |
|||
|
|
ние, полученное поразрядной дизъюнкцией (ИЛИ) |
|||
|
|
его битового представления с битовым представле |
|||
|
|
нием целочисленного операнда правой части а | = b |
|||
|
|
эквивалентно а = а | Ь; |
|||
А= |
- присваивание |
после |
исключающего поразрядного |
||
|
|
“ИЛИ’’\ присвоить целочисленному операнду левой |
|||
|
|
части значение, полученное применением поразряд |
|||
|
|
ной операции исключающего ИЛИ к битовым пред |
|||
|
|
ставлениям |
значений |
обоих операндов z A= x + y |
эквивалентно г - г А (х + у).
Обратите внимание, что для всех составных операций при
сваивания |
форма присваивания E l ор= Е2 эквивалентна Е1 = |
E l op (Е2), |
где ор - обозначение операции. |
Глава 1. Базовые понятия языка |
41 |
Операции выбора компонентов структурированного объ екта:
. (точка) - прямой выбор (выделение) компонента структу рированного объекта, например объединения или структуры (ранг 1). Формат применения опера ции:
имя структурированного объекта, имяком по нента
-> - косвенный выбор (выделение) компонента струк турированного объекта, адресуемого указателем (ранг 1). При использовании операции требуется, чтобы с объектом был связан указатель (указателям посвящена гл. 4.). В этом случае фор мат применения операции имеет вид:
указатель на структурированный объект -> имякомпонента
Так как операции выбора компонентов структурированных объектов используются со структурами и объединениями, то необходимые пояснения и примеры приведем позже, введя пе речисленные понятия и, кроме того, аккуратно определив указа тели.
Запятая в качестве операции (ранг 15)
Несколько выражений, разделенных запятыми вычисля ются последовательно слева направо. В качестве результата со храняются тип и значение самого правого выражения. Таким образом, операция "запятая" группирует вычисления слева на право. Тип и значение результата определяются самым правым из разделенных запятыми операндов (выражений). Значения всех левых операндов игнорируются. Например, если перемен ная х имеет тип int, то значением выражения (х=3, 3*х) будет 9, а переменная х примет значение 3.
Скобки в качестве операций
Круглые () и квадратные [ ] скобки играют роль бинарных операций (ранг 1) при вызове функций и индексировании эле ментов массивов. Для программиста, начинающего использо-