Константы перечисляемого типа.
enumтип_перечисления (список_именованных_констант);
Если в списке нет ни одного элемента со знаком «=», то значения констант начинаются с 0 и увеличиваются на 1 слева направо.
Например:
enum (ONE=1, TWO, THREE, FOUR);
enumDAY (SUNDAY, MONDAY);
Таким образом, TWO равно 2, SUNDAY имеет значение 0.
5.2. Строки или строковые константы
Формально строки (в соответствии со стандартом) не относятся к константам языка Си, и представляют собой отдельный тип его лексем. Для них в литературе используется еще одно название «строковые литералы». Строковая константа определяется как последовательность символов, заключенная в двойные кавычки (не в апострофы):
“образец строки”. Среди них могут быть и Esc последовательности.
5.2.1. Переменные и именованные константы
Переменная как объект.При задании значения переменной в соответствующую ей область памяти помещается код этого значения. Доступ к значению переменной наиболее естественно обеспечивает ее имя, а доступ к участку памяти возможен только по его адресу.
Определение переменных.Каждая переменная перед ее использованием в программе должна быть определена, т.е. для переменной должна быть выделана память. Размер участка памяти, выделяемой для переменной, и интерпретация содержимого зависят от типа, указанного в определении переменной. Определены целочисленные типы (перечислены в порядке неубывания длины внутреннего представления):
char – целый длиной не менее 8 бит;
short int – короткий целый (допустима аббревиатура short);
int - целый;
long - длинный целый.
Каждый из целочисленных типов может быть определен либо как знаковый signedлибо как беззнаковый unsigned (по умолчанию signed).
Различия между этими двумя типами – в правилах интерпретации старшего бита внутреннего представления. Спецификатор signedтребует, чтобы старший бит внутреннего представления воспринимался как знаковый; unsigned означает, что старший бит внутреннего представления входит в код представляемого числового значения, которое считается в этом случае беззнаковым. Выбор знакового или представления определяет предельные значения, которые можно представить с помощью описанной переменной.
Допустимо отдельное использование обозначений (спецификаторов) «знаковости». При этом
signed эквивалентно signed int;
unsigned эквивалентно unsigned int;
Примеры определения целочисленных переменных:
char symbol, cc;
unsigned charcode;
intnumber, row;
unsigned longlong_number;
Стандартом языка введены следующие вещественные типы:
float - вещественный одинарной точности;
double - вещественный удвоенной точности;
long double - вещественный максимальной точности.
Значение всех вещественных типов в ЭВМ представляются с «плавающей точкой», т.е. с мантиссой и порядком, как было рассмотрено при определении констант.
Например:
float x, X, cc3;
double e, S3;
Предельные значения переменных.Стандарт требует, чтобы для значений типа short и int было отведено не менее 16 бит, для long – не менее 32 бит. При этом размер long должен быть не менее размера int, а int – не менее short. Ниже в таблице приведены возможные значения типов данных для конкретной реализации.
Таблица 2. Предельные значения переменных
Тип данных | Размер, бит | Диапазон значений |
unsigned char | 0…255 | |
char | -128…127 | |
enum | -32768…32767 | |
unsigned int | 0…65535 | |
short int (short) | -32768…32767 | |
unsigned short | 0…65535 | |
int | -32768…32767 | |
unsigned long | 0…4294967295 | |
long | -2147483648…2147483647 | |
float | 3.4E-38…3.4E+38 | |
double | 1.7E-308…1.7E+308 | |
long double | 3.4E-4932…1.1E_4932 |
Инициализация переменных.В соответствии с синтаксисом языка переменные автоматической памяти после определения по умолчанию имеют неопределенные значения. Однако, переменным можно присваивать начальные значения, явно указывая их в определениях:
тип имя_переменной= начальное_значение;
Этот прием назван инициализацией. В отличие от присваивания, которое осуществляется в процессе выполнения программы, инициализация выполняется при выделении для переменной участка памяти. Примеры определения с инициализацией:
float pi=3.1415, cc=1.23;
Именованные константы.В языке Си, кроме переменных могут быть определены константы, имеющие фиксированные названия (имена). В качестве имен констант используются произвольно выбираемые программистом идентификаторы, не совпадающие с ключевыми словами и с другими именами объектов. Традиционно принято, что для обозначений констант выбирают идентификаторы из больших букв латинского алфавита и символов подчеркивания. Такое соглашение позволяет при просмотре большого текста программы на языке Си легко отличать имена переменных от названий констант.
Первая возможность определения именованных констант – это перечисляемые константы, вводимые с использованием служебного слова enum.
Вторую возможность вводить именованные константы обеспечивают определения такого вида:
const тип имя_константы=значение_константы;
Здесь const – квалификатор типа, указывающий, что определяемый объект имеет постоянное значение, т.е. доступен только для чтения; тип – один из типов объектов; имя_константы – идентификатор; значение_константы должно соответствовать ее типу. Примеры:
const double E=2.7182;
const F=765;
В последнем определении тип константы не указан, по умолчанию ей приписывается тип int.
Третья возможность вводить именованные константы обеспечивает препроцессорная директива
#define имя_константы значение константы
Точка с запятой в определении отсутствует.
Пример:
#define EULER 2.718282
Отличие определения именованной константы от определения препроцессорной константы с таким же значением состоит внешне в том, что в определении константы Е явно задается ее тип, а при препроцессорном определении константы EULER ее тип определяется «внешним видом» значения константы.
Однако различия между обычной именованной константой и препроцессорной константой, вводимой директивой #define, гораздо глубже и принципиальнее. До начала компиляции текст программы на языке Си обрабатывается специальным компонентом транслятора – препроцессором. Если в тексте встречается директива
#define EULER 2.718282
а ниже ее в тексте используется имя константы EULER, например, в таком виде:
double mix= EULER;
d=alfa*EULER;
то препроцессор заменит каждое обозначение EULER на ее значение и сформирует такой текст:
double mix=2.718282;
d=alfa*2.718282;
Далее текст от препроцессора поступает к компилятору, который уже «и не вспомнит» о существовании имени EULER, использованного в препроцессорной директиве #define.
Именно с помощью набора именованных препроцессорных констант стандарт языка Си рекомендует авторам компиляторов определять предельные значения всех основных типов данных. Для этого в языке определен набор фиксированных имен, каждое из которых является именем одной из констант, определяющих то или иное предельно значение.
Например:
FLT_MAX - максимальное число с плавающей точной типа float;
CHAR_DIT - количество битов в байте;
INT_MIN - минимальное значение для данных типа int.
Чтобы использовать в программе указанные именованные препроцессорные константы, недостаточно записать их имена в программе. Предварительно в текст программы необходимо включить препроцессорную директиву такого вида:
#include <имя_заголовочного _файла>,
где в качестве имени_заголовочного _файла подставляется:
limits.h - для данных целых типов;
float.h - для вещественных данных.
Такой подход к определению предельных значений с помощью препроцессорных констант, сохраняемых в библиотечных файлах, позволяет писать программы, не зависящие от реализации, что обеспечивает их достаточную мобильность.
5.3. Операция
Знаки операций.Для формирования и последующего вычисления выражений используются операции. Для изображения одной операций в большинстве случаев используется несколько символов.
Таблица 3. Знаки операций.
Ранг | Операция | Ассоциативность |
() [ ] -> . | ® | |
! ~ + - ++ -- & * (мин) sizeof | ||
* / % (мультикативные бинарные) | ® | |
+ - (аддитивные бинарные) | ® | |
<< >> (поразрядного сдвига) | ® | |
< <= >= > (отношение) | ® | |
== != (отношение) | ® | |
& (поразрядная конъюнкция «ИЛИ») | ® | |
^ (поразрядное исключающее «ИЛИ») | ® | |
| (поразрядная дизъюнкция «ИЛИ») | ® | |
&& (конъюнкция «И») | ® | |
|| (дизъюнкция «ИЛИ») | ® | |
? : | ||
= *= /= %= += -= &= ^= |= <<= >>= | ||
, (операция «запятая») | ® |
Унарные (одноместные) операции.Для изображения одноместных префиксных о постфиксных операций используются следующие символы:
& - операция получения адреса операнда (ранг 2);
* - операция обращения по адресу, т.е. раскрытия ссылки, иначе операция разыменования (доступа по адресу к значению того объекта, на который указывает операнд). Операндом должен быть указатель (ранг 2);
- - унарный минус, изменяет знак арифметического операнда (ранг 2);
+ - унарный плюс, введен для симметрии с унарным минусом (ранг 2);
~ - поразрядное инвертирование внутреннего двоичного кода целочисленного аргумента – побитовое отрицание (ранг 2);
! - НЕ логическое отрицание значения операнда (ранг 2). Отрицание любого ненулевого числа будет 0, а отрицанием нуля будет 1. Таким образом: !1 равно 0; !2 равно 0; !0 равно 1;
++ - увеличение на единицу (инкремент или автоувеличение – ранг 2); имеет две формы:
префиксная операция – увеличение значения операнда на 1 до его использования. Ассоциативность справа в соответствии со стандартом.
постфиксная операция – увеличение значения операнда на 1 после его использования. Ассоциативность слева в соответствии со стандартом.
Операнд для операции ++ (и для операции --) не может быть константой либо произвольным выражением. Записи ++5 или 84++ будут неверными. ++(j+k) также неверная запись. Операндами унарных операций ++ и – должны быть всегда модифицируемые именующие выражения (l – value, left – value, l – значение, леводопустимое выражение). Термины «леводопустимое выражение» и «l-значение» происходят от объяснения действия операции присваивания Е = D, в которой операнд Е слева от знака операции присваивания может быть только модифицируемым l-значением. Примером модифицируемого l-значения служит имя переменной, которой выделена память. Таким образом, l-значение – ссылка на область памяти, значение которой доступно изменениям;
-- - уменьшение на единицу (декремент или автоуменьшение – ранг 2) – унарная операция, операндом которой должно быть леводопустимое выражение, т.е. не константа и не выражение:
префиксная операция – уменьшение на 1 значения операнда до его использования;
постфиксная операция – уменьшение на 1 значения операнда после его использования;
sizeof - операция (ранг 2) вычисление размера (в байтах) для объекта того типа, который имеет операнд. Разрешены два формата операции:
sizeof выражение
sizeof (тип)
sizeof не вычисляет значения выражения, а только определяет его тип, для которого затем вычисляется размер.
Бинарные (двуместные) операции делятся на следующие группы:
§ аддитивные;
§ мультипликативные;
§ сдвигов;
§ поразрядные;
§ операции отношений;
§ логические;
§ присваивания;
§ выбора компонента структурированного объекта;
§ операция «запятая»;
§ скобки в качестве операций.
Аддитивные операции
+ - бинарный плюс – сложение арифметических операндов или сложение указателя с целочисленным операндом (ранг 4);
- - бинарный минус – вычитание арифметических операндов или вычитание указателей (ранг 4).
Мультипликативные операции:
* - умножение операндов арифметического типа (ранг 3);
/ - деление операндов арифметического типа (ранг 3). При целочисленных операндах абсолютное значение результата округляется до целого. Например, 20/3 равно 6.
% - получение остатка от деления целочисленных операндов (деление по модулю – ранг 3). При неотрицательных операндах остаток положительный. В противном случае остаток определяется реализацией.
Операции сдвига (определены только для целочисленных операндов). Формат выражения с операцией сдвига:
<< - сдвиг влево битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого целочисленного операнда (ранг 5);
>> - сдвиг вправо битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого целочисленного операнда (ранг 5).
Поразрядные операции:
& - поразрядная конъюнкция (И) битовых представлений значений целочисленных операндов (ранг 8);
| - поразрядная дизъюнкция (ИЛИ) битовых представлений значений целочисленных операндов (ранг 10);
^ - поразрядное исключающее ИЛИ битовых представлений значений целочисленных операндов (ранг 9).
Результат выполнения операций сдвига и поразрядных операций:
4<<2 равняется 16
5>>1 равняется 2
6&5 равняется 4
6>5 равняется 7
6^5 равняется 5
Операции отношений (сравнения):
< меньше, чем (ранг 6);
> больше, чем (ранг 6);
<= меньше или равно (ранг 6);
>= больше или равно (ранг 6);
== равно (ранг 7);
!= не равно (ранг 7).
Операнды операций отношений должны быть арифметического типа или могут быть указателями. Результат целочисленный: 0 (ложь) или 1 (истина). Последние две операции (операции сравнения на равенство) имеют более низкий приоритет по сравнению с остальными операциями отношений. Таким образом, выражение (x<B= A<x) есть 1, когда x, A,B равны.
Логические бинарные операции:
&& - конъюнкция (И) арифметических операндов или отношений (ранг 2). Целочисленный результат 0 (ложь) или 1 (истина).
|| - дизъюнкция (ИЛИ) арифметических операндов или отношений (ранг 12). Целочисленный результат 0 (ложь) или 1 (истина).