Базовые типы данных целых чисел
В Си имеется возможность использовать машинные слова различной размерности для определения целых переменных как в знаковой, так и в беззнаковой форме. Для этого используются следующие служебные слова:
-char -размерность переменной -байт;
-int -размерность переменной -стандартное машинное слово;
-short -укороченная размерность, меньшая либо равная int;
-long -размерность переменной -двойное слово;
-signed -форма представления целого со знаком;
-unsigned -беззнаковая форма представления целого.
Из этих служебных слов можно составить определение типа данных целой переменной. При этом signed считается заданным по умолчанию, а unsigned int сокращается до int :
int i; // целое со знаком, слово
char c; // целое со знаком, байт
unsigned char uc; // целое без знака, байт
unsigned u; // целое без знака, слово
long l; // целое со знаком, двойное слово
unsigned long ul; // целое без знака, двойное слово
short s; // целое со знаком, короткое слово
/ / (слово или байт)
Для определения размерности различных переменных и типов в Си имеется специальная операция, которая возвращает размерность типа данных, переменной и значения выражения выражения, подсчитанную в байтах:
sizeof (int) // размерность типа данных int - 2
sizeof l // размерность переменной типа long - 4
sizeof(i+2.0) // размерность значения выражения типа double - 8
В заключение еще раз вернемся к знаковой и беззнаковой форме представления и к взаимоотношениям между ними и транслятором. Для транслятора обе они -суть машинные слова одинаковой или разной длины. Поэтому когда речь идет о записи (присваивании) значения беззнаковой переменной в переменную со знаком (или наоборот), транслятор просто рассматривает это как копирование машинных слов без каких-либо преобразований. Например, знаковое -1 превращается в беззнаковое 0xFFFF или 65535. Поэтому когда в программе меняется форма представления целого со знаком в беззнаковую (и наоборот), то это не сопровождается абсолютно никакими действиями (машинными командами).
Одной из форм представления целого является также ПЕРЕЧИСЛИМЫЙ ТИП enum. Переменная такого типа принимает ряд значений, которые перечислены в отдельном определении типа enum в виде идентификаторов(имен). Каждому идентификатору соответствует явно заданное или неявно полученное при перечислении значение:
enum BOOL { FALSE, TRUE}; // 0,1
enum digit { four=4,one=1,two,three }; // 4,1,2,3.
BOOL x; ... if (x==FALSE) ...
digit D; ... D = ten; ...
В данном примере перечислимый тип BOOL имеет два значения - 0 и 1, которые обозначаются соответственно как FALSE и TRUE. Имя BOOL затем используется для определения переменной этого типа с именем x, которая может принимать указанные значения. То же самое производится в типом digit и переменной D. Как видим, перечислимый тип не выходит за рамки обычного целого. Более того, любая переменная такого типа в трансляторе реализуется как обычное целое и в процессе выполнения программы не проверяется на допустимость тех или иных значений. Например, можно написать:
x = 3; // Присвоить 3 переменной типа digit
Тогда зачем же они нужны? Для придания большей ясности программе: обозначения ограниченного количества вариантов, признаков и т.д..