Для начала несколько вопросов:
- Тип
charпо умолчанию знаковый или нет? Аint? - Сколько бит в
char? - Какое максимальное число гарантированно можно поместить в
int? А минимальное? - Тип
longопределённо больше, чемchar, не так ли?
Разумеется, экспериментально искать ответы на эти вопросы с помощью вашего любимого компилятора в вашей любимой системе на вашем любимом компьютере1 — не лучшая идея. Мы говорим о стандарте языка (С99 и новее).
Если вы уверенно сможете правильно ответить на эти вопросы, тогда эта статья не для вас. В противном случае десять минут, потраченные на её чтение, будут весьма полезны.
- Знаковые оба.
- 8.
- 2147483647. -2147483648.
- Конечно, кэп.
char— не регламентируется,int— знаковый.- Не менее 8.
- 32767. -32767
- Вообще говоря, нет.
Про signed и unsigned
Все целочисленные типы кроме char, по умолчанию знаковые (signed).
С char ситуация сложнее. Стандарт устанавливает три различных типа: char, signed char, unsigned char. В частности, указатель типа (signed char *) не может быть неявно приведён к типу (char *).
Хотя формально это три разных типа, но фактически char эквивалентен либо signed char, либо unsigned char — на выбор компилятора (стандарт ничего конкретного не требует).
О размере char
Тип char является абстракцией машинного байта. Важность этого типа проявляется в том, что С может адресовать память только с точностью до байта. На большинстве архитектур размер байта равен 8 бит, но бывают и исключения. Например, процессоры с 36-битной архитектурой как правило имеют 9-битный байт, а в некоторых DSP от Texas Instruments байты состоят из 16 или 32 бит. Древние архитектуры могут иметь короткие байты из 4, 5 или 7 бит.
Стандарт С вынужден отказаться от допотопных архитектур и требует, чтобы байты были как минимум 8-битные. Конкретное значение (CHAR_BIT) для данной платформы записано в заголовочном файле limits.h.
Размеры целочисленных типов в С
C переносимый, поэтому в нём базовые целочисленные типы (char, short, int и др.) не имеют строго установленного размера, а зависят от платформы. Однако эти типы не были бы переносимы, если бы
их размеры были совершенно произвольные: стандарт устанавливает минимальные диапазоны принимаемых значений для всех базовых целочисленные типов. А именно,
signed char:-127...127 (не -128...127; аналогично другие типы)unsigned char: 0...255signed short: -32767...32767unsigned short: 0...65535signed int: -32767...32767unsigned int: 0...65535signed long: -2147483647...2147483647unsigned long: 0...4294967295signed long long: -9223372036854775807...9223372036854775807unsigned long long: 0...18446744073709551615
То есть как минимум char 8-битный, short 16-битный, int 16-битный (а не 32!), long 32-битный, long long 64-битный. Обратите внимание на short и int.
Сверху размеры целочисленных типов стандарт не ограничивает, только снизу. Таким образом, вполне законны ситуации типа sizoof(char)>sizeof(long). Для некоторых DSP от Texas Instruments установлено sizoof(char)=sizeof(long)=32 (байт у них 32-битный) — горя не знают.
Конкретные значения этих диапазонов для данной платформы указаны заголовочном файле limits.h.
Новые типы в С99
После того, как C99 добавил тип long long, целочисленных типов и путаницы стало ещё больше. Чтобы навести порядок, стандарт ввёл заголовочный файл inttypes.h, где определяются типы вроде int16_t (равно 16 бит), int_least16_t (по крайней мере 16 бит), int_fast16_t (по крайней мере 16 бит, работа с этим типом наиболее быстрая на данной платформе) и т. п.
От типов вроде int16_t со строгим указанием размера страдает переносимость: скажем, на архитектуре с 9-битным байтом может просто не найтись 16-битного регистра. Но учитывая, что какой бы код вы не писали, чуть менее чем во всех случаях целевая архитектура фиксирована даже в худшем случае точностью до семейства (x86, AVR), внутри которого, размер байта не может вдруг поменяться, то переносимость фактически сохраняется. Более того, типы вроде int16_t оказались даже более популярными, чем int_least16_t и int_fast16_t, а при низкоуровневом программировании (микроконтроллеры, драйверы устройств) и подавно, ибо там зачастую неопределённость размера переменной просто непозволительна.
1 Для удобства тройку архитектура+ОС+компилятор далее будем называть просто платформой.
Автор: azudem
