Главная страница

Курс на Си. Подбельский. Курс программирования на Си. В., Фомин С. С. Курс программирования на языке Си Учебник


Скачать 1.57 Mb.
НазваниеВ., Фомин С. С. Курс программирования на языке Си Учебник
АнкорКурс на Си
Дата18.02.2023
Размер1.57 Mb.
Формат файлаdocx
Имя файлаПодбельский. Курс программирования на Си.docx
ТипУчебник
#943863
страница5 из 42
1   2   3   4   5   6   7   8   9   ...   42


FLT_MAX - максимальное число с плавающей точкой типа float;

  • CHAR_BIT - количество битов в байте;

  • INT_MIN - минимальное значение для данных типа int.

    Общий список стандартных препроцессорных именованных конс­тант для арифметических данных дан в приложении 2.

    Чтобы использовать в программе указанные именованные пре- процессорные константы, недостаточно записать их имена в прог­рамме. Предварительно в текст программы необходимо включить препроцессорную директиву такого вида:

    #include <имя_заголовочного_файла>,

    где в качестве имени_заголовочного_файла подставляются: limits.h - для данных целых типов;

    float.h - для вещественных данных.

    В заголовочный файл limits.h авторы компилятора поместили набор препроцессорных директив, среди которых есть такие (при­ведены значения в шестнадцатеричном виде для Turbo C):

    #define CHAR_BIT 8

    #define SHRT_MAX 0x7FFF

    #define LONG_MAX 0x7FFFFFFFL

    В заголовочном файле float.h находятся директивы, определяю­щие константы, связанные с представлением данных вещественных типов. Например:

    #define FLT_MIN 1.17549435E-38F

    #define DBL_MIN 2.2250738585072014E-308

    #define DBL_EPSILON 2.2204460492503131E-16

    Значения этих предопределенных на препроцессорном уровне констант в соответствии со стандартом языка в конкретных компи­ляторах могут быть несколько иными, отличными от тех, что при­ведены в таблицах приложения 2.

    Подробно о возможностях препроцессорных средств будет го­вориться в главе 3. Сейчас достаточно знать, что, записав в тексте своей программы директиву

    #include

    можно использовать в программе стандартные именованные кон­станты CHAR_BIT, SHRT_MIN и т. д. (см. приложение 2), а уж их

    значениями будут те числа, которые включили в директивы #define авторы конкретного компилятора и конкретной библиотеки.

    Если включить в программу директиву

    #include

    то станут доступными именованные константы предельных значе­ний числовых данных вещественных типов (см. приложение 2).

    Такой подход к определению предельных значений с помощью препроцессорных констант, сохраняемых в библиотечных файлах, позволяет писать программы, не зависящие от реализации, что обес­печивает их достаточную мобильность. Программист использует в программе стандартные имена (обозначения) констант, а их зна­чения определяются версией реализации, то есть конкретным ком­пилятором и его библиотеками.

    1.4. Операции

    В этом параграфе достаточно лаконично определяются все опе­рации языка Си и приводится таблица их приоритетов. Хотя в бли­жайших параграфах (где вводятся выражения и основные операто­ры языка) нам понадобятся не все знаки операций и нередко будет достаточно интуитивного представления об их старшинстве и ассо­циативности, но материал этого параграфа слишком важен, чтобы говорить о нем позже. В последующих главах применение операций языка будет рассмотрено подробно, но к таблице приоритетов стоит обращаться и при дальнейшем чтении, и при написании программ.

    Знаки операций. Для формирования и последующего вычисле­ния выражений используются операции. Для изображения одной операции в большинстве случаев используется несколько символов. В табл. 1.4 приведены все знаки операций, определенные стандартом языка. Операции в таблице разбиты на группы в соответствии с их рангами.

    За исключением операций "[ ]", "( )" и "?:", все знаки операций распознаются компилятором как отдельные лексемы. В зависимости от контекста одна и та же лексема может обозначать разные опе­рации, то есть один и тот же знак операции может употребляться в различных выражениях и по-разному интерпретироваться в за­висимости от контекста. Например, бинарная операция & - это поразрядная конъюнкция, а унарная операция & - это операция получения адреса.

    Операции ранга 1 имеют наивысший приоритет. Операции од­ного ранга имеют одинаковый приоритет, и если их в выражении несколько, то они выполняются в соответствии с правилом ассоциа­тивности либо слева направо (^), либо справа налево (^—). Если один и тот же знак операции приведен в таблице дважды (напри­мер, знак *), то первое появление (с меньшим по номеру, то есть старшим по приоритету, рангом) соответствует унарной операции, а второе - бинарной.

    Опишем кратко возможности отдельных операций.

    Таблица 1.4. Приоритеты (ранги) операций

    Ранг

    Операции

    Ассоциативность

    1

    ( ) [ ] -> .

    ^

    2

    ! + - ++ -- & * (тип) sizeof

    ^

    3

    * / % (мультипликативные бинарные)

    ^

    4

    + - (аддитивные бинарные)

    ^

    5

    << >> (поразрядного сдвига)

    ^

    6

    < <= >= > (отношения)

    ^

    7

    == != (отношения)

    ^

    8

    & (поразрядная конъюнкция «И»)

    ^

    9

    л (поразрядное исключающее «ИЛИ»)

    ^

    10

    | (поразрядная дизъюнкция «ИЛИ»)

    ^

    11

    && (конъюнкция «И»)

    ^

    12

    || (дизъюнкция «ИЛИ»)

    ^

    13

    ?: (тернарная операция)

    ^

    14

    = *= /= %= += -= &= л= |= <<= >>=

    ^

    15

    , (операция «запятая»)

    ^

    Унарные (одноместные) операции. Для изображения одномест­ных префиксных и постфиксных операций используются следую­щие символы:

    • & - операция получения адреса операнда (ранг 2);

    • * - операция обращения по адресу, то есть раскрытия ссылки, иначе операция разыменования (доступа по адресу к значению того объекта, на который указывает операнд). Операндом дол­жен быть указатель (ранг 2);

    • унарный минус, изменяет знак арифметического операнда

    (ранг 2);

    • + - унарный плюс, введен для симметрии с унарным минусом (ранг 2);

    • поразрядное инвертирование внутреннего двоичного кода

    целочисленного аргумента - побитовое отрицание (ранг 2);

    • ! - логическое отрицание (НЕ) значения операнда (ранг 2). Применяется к скалярным операндам. Целочисленный ре­зультат 0 (если операнд ненулевой, то есть истинный) или 1 (если операнд нулевой, то есть ложный). Напомним, что в качестве логических значений в языке используют целые числа: 0 - ложь и не нуль, то есть (!0) - истина. Отрица­нием любого ненулевого числа будет 0, а отрицанием нуля будет 1. Таким образом: !1 равно 0; !2 равно 0; !(-5) равно 0; !0 равно 1;

    • ++ - увеличение на единицу (инкремент или автоувеличе­ние - ранг 2); имеет две формы:

    • префиксная операция - увеличение значения операнда на 1 до его использования. Ассоциативность справа в соответ­ствии со стандартом;

    • постфиксная операция - увеличение значения операнда на 1 после его использования. Ассоциативность слева в соот­ветствии со стандартом.

    Операнд для операции ++ (и для операции --) не может быть константой либо произвольным выражением. Записи ++5 или 84++ будут неверными. ++(j+k) - также неверная запись. Операндами унарных операций ++ и -- должны быть всегда модифицируемые именующие выражения (L-value, leftvalue, l-значение, леводопустимое выражение). Термины «леводопус­тимое выражение» и «l-значение» происходят от объяснения действия операции присваивания E = D, в которой операнд E слева от знака операции присваивания может быть только модифицируемым l-значением. Примером модифицируемого l-значения служит имя переменной, которой выделена память. Таким образом, l -значение - ссылка на область памяти, значе­ние которой доступно изменениям;

    -- - уменьшение на единицу (декремент или автоуменьше­ние - ранг 2) - унарная операция, операндом которой должно быть леводопустимое выражение, то есть не константа и не выражение:

    • префиксная операция - уменьшение на 1 значения операнда до его использования;

    • постфиксная операция - уменьшение на 1 значения операн­да после его использования;

    sizeof - операция (ранг 2) вычисления размера (в байтах) для объекта того типа, который имеет операнд. Разрешены два формата операции:

    • sizeof выражение;

    • sizeof (тип);

    sizeof не вычисляет значения выражения, а только определяет его тип, для которого затем вычисляется размер.

    Бинарные (двуместные) операции делятся на следующие группы: □ аддитивные;

    • мультипликативные;

    • сдвигов;

    • поразрядные;

    • операции отношений;

    • логические;

    • присваивания;

    • выбора компонента структурированного объекта;

    • операция «запятая»;

    • скобки в качестве операций.

    Аддитивные операции:

    • + - бинарный плюс - сложение арифметических операндов или сложение указателя с целочисленным операндом (ранг 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;

    • 5>>1 равняется 2;

    • 6&5 равняется 4;

    • 6 | 5 равняется 7;

    • 6Л5 равняется 3.

    Напоминаем, что двоичный код для 4 равен 100, для 5 - это 101, для 6 - это 110 и т. д. При сдвиге влево на две позиции код 100 ста­новится равным 10000 (десятичное значение равно 16). Остальные результаты операций сдвига и поразрядных операций могут быть прослежены аналогично.

    Обратите внимание, что сдвиг влево на n позиций эквивалентен умножению значения на 2n, а сдвиг кода вправо уменьшает соот­ветствующее значение в 2n раз с отбрасыванием дробной части ре­зультата. (Поэтому 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;

    • += - присваивание после суммирования: присвоить операнду левой части сумму значений обоих операндов. 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 - обозначение операции.

    Операции выбора компонентов структурированного объекта:


  • написать администратору сайта