Базовые типы данных (кроме void) могут иметь различные спецификаторы[1], предшествующие им в тексте программы. Спецификатор типа так изменяет значение базового типа, чтобы он более точно соответствовал своему назначению в программе. Полный список спецификаторов типов:
signed
unsigned
long
short
Базовый тип int может быть модифицирован каждым из этих спецификаторов. Тип char модифицируется с помощью unsigned и signed, double — с помощью long. (Стандарт С99 также позволяет модифицировать long с помощью long, создавая таким образом long long, см. часть II). В табл. 2.1 приведены все допустимые комбинации типов данных с их минимальным диапазоном значений и типичным размером. Обратите внимание, в таблице приведены минимально возможные, а не типичные диапазоны значений. Например, если в компьютере арифметические операции выполняются над числами в дополнительных кодах (а именно так спроектированы почти все компьютеры!), то в диапазон значений целых попадут все целые числа от -32767 до 32768.
Тип | Типичный размер в битах | Минимально допустимый диапозон значений |
---|---|---|
char | 8 | от -127 до 127 |
unsigned char | 8 | от 0 до 255 |
signed char | 8 | от -127 до 127 |
int | 16 или 32 | от -32767 до 32767 |
unsigned int | 16 или 32 | от 0 до 65535 |
signed int | 16 или 32 | то же, что int |
short int | 16 | от -32767 до 32767 |
unsigned short int | 16 | от 0 до 65535 |
signed short int | 16 | то же, что short int |
long int | 32 | от -2 147 483 647 до 2 147 483 647 |
long long int | 64 | от -(263-1) до (263-1), добавлен стандартом C99 |
signed long int | 32 | то же, что long int |
unsigned long int | 32 | от 0 до 4 294 967 295 |
unsigned long long int | 64 | от 0 до (264-1), добавлен в C99 |
float | 32 | от 1E-37 до 1E+37, с точностью не менее 6 значащих десятичных цифр |
double | 64 | от 1E-37 до 1E+37, с точностью не менее 10 значащих десятичных цифр |
long double | 80 | от 1E-37 до 1E+37, с точностью не менее 10 значащих десятичных цифр |
Для целых можно использовать спецификатор signed, но в этом нет необходимости, потому что при объявлении целого он предполагается по умолчанию. Спецификатор signed чаще всего используется для типа char, который в некоторых реализациях по умолчанию может быть беззнаковым.
Целые числа со знаком и без знака отличаются интерпретацией нулевого бита числа. Если целое объявлено со знаком, компилятор считает, что нулевой бит содержит знак числа. Если в нулевом бите записан 0, число считается положительным, а если 1 — отрицательным.
В большинстве реализаций отрицательные числа представлены в двоичном дополнительном коде. Это значит, что для отрицательного числа все биты, кроме нулевого, инвертируются, к полученному числу добавляется 1, а нулевой бит устанавливается в 1.
Целые числа со знаком используются почти во всех алгоритмах, но абсолютная величина наибольшего из них составляет примерно только половину максимального целого без знака. Например, знаковое целое число 32767 в двоичном коде имеет вид
01111111 11111111
Если в нулевой бит записать 1, то оно будет интерпретироваться как —1. Однако если полученную запись рассматривать как представление числа, объявленного как unsigned int, то оно будет интерпретироваться как 65535.
Если спецификатор типа записать сам по себе (без следующего за ним базового типа), то предполагается, что он модифицирует тип int. Таким образом, следующие спецификаторы типов эквивалентны:
Спецификатор | То же самое |
---|---|
signed | signed int |
unsigned | unsigned int |
long | long int |
short | short int |
Хотя базовый тип int и предполагается по умолчанию, его, тем не менее, обычно указывают явно.
[1]Называются также описателями, модификаторами и квалификаторами.