Разница между int32, int, int32_t, int8 и int8_t

106

Я int32_tнедавно столкнулся с этим типом данных в программе C. Я знаю, что он хранит 32 бита, но нет intиint32 сделать то же самое?

Также я хочу использовать charв программе. Могу ли я использоватьint8_t вместо этого? В чем разница?

Подводя итог: в чем разница между int32, int, int32_t, int8 и int8_t в C?

linuxfreak
источник

Ответы:

124

Между int32и int32_t(а также между int8и int8_t) разница довольно проста: стандарт C определяет int8_tи int32_t, но не определяет ничего с именем int8или int32- последнее (если они вообще существуют), вероятно, из какого-то другого заголовка или библиотеки (скорее всего предшествует добавлению int8_tиint32_t в C99).

Обычный intсовсем немного отличается от других. Где int8_tи int32_tкаждый имеет указанный размер, intможет быть любым размером> = 16 бит. В разное время достаточно распространены и 16-битные, и 32-битные (а для 64-битной реализации, вероятно, должно быть 64 бит).

С другой стороны, intгарантированно присутствует в каждой реализации C, где int8_tи int32_tнет. Вероятно, остается открытым вопрос, имеет ли это значение для вас. Если вы используете C в небольших встроенных системах и / или старых компиляторах, это может быть проблемой. Если вы используете его в основном с современным компилятором на настольных / серверных машинах, вероятно, этого не будет.

Упс - пропустил часть про char. Вы бы использовали int8_tвместо char, если (и только если) вы хотите, чтобы целочисленный тип гарантированно имел размер ровно 8 бит. Если вы хотите хранить символы, вы, вероятно, захотите использовать charвместо этого. Его размер может быть разным (по количеству битов), но гарантированно равен одному байту. Одна небольшая странность: нет никакой гарантии того char, подписан или нет обычный простой (и многие компиляторы могут сделать это одним из них, в зависимости от флага времени компиляции). Если вам нужно убедиться, что он подписан или не подписан, вам нужно указать это явно.

Джерри Гроб
источник
1
@linuxfreak: Не уверен bool_t- никогда раньше не слышал об этом. Стандарт C определяет _Boolкак встроенный тип. boolопределяется, только если вы #include <stdbool.h>(как макрос, который расширяется до _Bool).
Джерри Коффин
5
Вы сказали: «Для 64-битной реализации (int), вероятно, должно быть 64 бит». На практике int является 32-битным на всех распространенных 64-битных платформах, включая Windows, Mac OS X, Linux и различные разновидности UNIX. Единственное исключение - Cray / UNICOS, но в наши дни они вышли из моды.
Сэм Уоткинс
6
@SamWatkins: Да, поэтому я осторожно сказал «должно быть», а не «есть». В стандарте говорится, что это «естественный размер, предложенный архитектурой», что (IMO) означает, что на 64-битном процессоре он действительно должен быть 64 -битным (хотя, к лучшему или худшему, вы совершенно правы, что обычно это не так. т). С более практической точки зрения, это очень удобно иметь тип 32-битную между типами в C89, и если ИНТ 64 бит, долго должен быть по крайней мере 64 бита тоже, так что не было бы часто быть не 32-бит тип.
Джерри Коффин
2
@barlop: Да. (И C, и C ++ требуют минимального диапазона 255 значений для char, поэтому требуется не менее 8 бит, но может быть больше).
Джерри Коффин,
2
У меня всегда было впечатление, что один байт - это ровно 8 бит, а не где-то 8 бит и выше
ErlVolton
18

Типы данных _t - это типы typedef в заголовке stdint.h, а int - это встроенный основной тип данных. Это делает _t доступным, только если существует stdint.h. int с другой стороны гарантированно существует.

Супермен
источник
2
Зачем использовать _t?
Deven
@Deven Чтобы избежать случая, когда ваш код работает где-то, но не где-то еще.
Франклин Ю
2

Всегда помните, что «размер» является переменным, если он не указан явно, поэтому, если вы объявляете

 int i = 10;

В некоторых системах это может привести к 16-битному целому числу компилятором, а в некоторых других - к 32-битному целому числу (или 64-битному целому числу в более новых системах).

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

 typedef short INT16;
 typedef int INT32;
 typedef long INT64; 

Начиная с C99, дизайнеры добавили заголовочный файл stdint.h, который по существу использует аналогичные определения типов.

В системе на базе Windows вы можете видеть записи в заголовочном файле stdin.h как

 typedef signed char       int8_t;
 typedef signed short      int16_t;
 typedef signed int        int32_t;
 typedef unsigned char     uint8_t;

Есть нечто большее, например, целочисленные типы с минимальной шириной или целые числа с точной шириной, я думаю, неплохо изучить stdint.h для лучшего понимания.

Науманн
источник
1
В вашем коде есть опечатка:, typedef short INT16;нет typedefs short INT16.
Galaxy