В чем разница между int и long в C ++? - PullRequest
110 голосов
/ 07 ноября 2008

Поправь меня, если я ошибаюсь,

int составляет 4 байта с диапазоном значений от -2 147 483 648 до 2 147 483 647 (2 ^ 31)
long - 4 байта с диапазоном значений от -2 147 483 648 до 2 147 483 647 (2 ^ 31)

Какая разница в C ++? Можно ли их использовать взаимозаменяемо?

Ответы [ 9 ]

101 голосов
/ 07 ноября 2008

Это зависит от реализации.

Например, в Windows они одинаковы, но, например, в системах Alpha long был 64 бит, тогда как int был 32 бит. Эта статья описывает правила для компилятора Intel C ++ на переменных платформах. Подведем итог:

  OS           arch           size
Windows       IA-32        4 bytes
Windows       Intel 64     4 bytes
Windows       IA-64        4 bytes
Linux         IA-32        4 bytes
Linux         Intel 64     8 bytes
Linux         IA-64        8 bytes
Mac OS X      IA-32        4 bytes
Mac OS X      Intel 64     8 bytes  
76 голосов
/ 07 ноября 2008

Единственная гарантия, которую вы имеете:

sizeof(char) == 1
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

// FROM @KTC. The C++ standard also has:
sizeof(signed char)   == 1
sizeof(unsigned char) == 1

// NOTE: These size are not specified explicitly in the standard.
//       They are implied by the minimum/maximum values that MUST be supported
//       for the type. These limits are defined in limits.h
sizeof(short)     * CHAR_BIT >= 16
sizeof(int)       * CHAR_BIT >= 16
sizeof(long)      * CHAR_BIT >= 32
sizeof(long long) * CHAR_BIT >= 64
CHAR_BIT         >= 8   // Number of bits in a byte

Также см .: Гарантируется ли long как минимум 32 бита?

13 голосов
/ 07 ноября 2008

При компиляции для x64 разница между int и long составляет где-то между 0 и 4 байтами, в зависимости от того, какой компилятор вы используете.

GCC использует модель LP64, что означает, что целые числа являются 32-разрядными, а длинные - 64-разрядными в 64-разрядном режиме.

Например, MSVC использует модель LLP64, что означает, что как целые, так и длинные являются 32-битными, даже в 64-битном режиме.

12 голосов
/ 07 ноября 2008

Сама спецификация C ++ (старая версия, но достаточно хорошая для этого) оставляет это открытым.

Существует четыре целых типа со знаком: 'signed char', 'short int', 'int' и 'long int'. В этом список, каждый тип обеспечивает как минимум много памяти, как те, которые предшествуют ему в список. Простые интты имеют естественный размер, предложенный архитектурой среда исполнения *;

[Сноска: то есть достаточно большая, чтобы содержать любое значение в диапазоне INT_MIN и INT_MAX, как определено в заголовок <climits>. --- конец foonote]

7 голосов
/ 07 ноября 2008

Как указывает Кевин Хэйнс, интты имеют естественный размер, предложенный средой исполнения, который должен соответствовать INT_MIN и INT_MAX.

Стандарт C89 утверждает, что UINT_MAX должно быть не менее 2 ^ 16-1, USHRT_MAX 2 ^ 16-1 и ULONG_MAX 2 ^ 32-1. Это делает подсчет битов по меньшей мере 16 для коротких и целых и 32 для длинных. Для символа char явно указывается, что он должен иметь не менее 8 бит (CHAR_BIT). C ++ наследует эти правила для файла limit.h, поэтому в C ++ мы предъявляем те же фундаментальные требования к этим значениям. Однако вы должны , а не получить из того, что int не менее 2 байт. Теоретически, char, int и long могут быть равны 1 байту, в этом случае CHAR_BIT должно быть не менее 32. Просто помните, что «byte» всегда имеет размер char, поэтому, если char больше, байт не только 8 бит больше.

6 голосов
/ 07 ноября 2008

Это зависит от вашего компилятора. Вам гарантировано, что long будет по крайней мере таким же большим, как int, но вам не гарантировано, что оно будет больше.

5 голосов
/ 07 ноября 2008

Опираясь на реализацию поставщика примитивов размеров примитивов Вернусь, чтобы преследовать вас, если вы когда-нибудь скомпилируете свой код на другом машинная архитектура, ОС или компилятор другого производителя.

Большинство поставщиков компиляторов предоставляют заголовочный файл, который определяет примитивные типы с эксплицировать размеры шрифтов. Эти примитивные типы следует использовать, когда код может быть перенесен другому компилятору (читайте это как ВСЕГДА в КАЖДОМ экземпляре). Например, большинство компиляторов UNIX имеют int8_t uint8_t int16_t int32_t uint32_t. Microsoft имеет INT8 UINT8 INT16 UINT16 INT32 UINT32. Я предпочитаю Borland / CodeGear's int8 uint8 int16 uint16 int32 uint32. Эти имена также дают небольшое напоминание о размере / диапазоне предполагаемого значения.

В течение многих лет я использовал явные примитивные имена типов Borland. и #include следующий заголовочный файл C / C ++ (primitive.h) который предназначен для определения явных примитивных типов с этими именами для любого компилятора C / C ++ (этот заголовочный файл может на самом деле не охватывать каждый компилятор, но он охватывает несколько компиляторов, которые я использовал в Windows, UNIX и Linux, он также (пока) не определяет 64-битные типы).

#ifndef primitiveH
#define primitiveH
// Header file primitive.h
// Primitive types
// For C and/or C++
// This header file is intended to define a set of primitive types
// that will always be the same number bytes on any operating operating systems
// and/or for several popular C/C++ compiler vendors.
// Currently the type definitions cover:
// Windows (16 or 32 bit)
// Linux
// UNIX (HP/US, Solaris)
// And the following compiler vendors
// Microsoft, Borland/Imprise/CodeGear, SunStudio,  HP/UX
// (maybe GNU C/C++)
// This does not currently include 64bit primitives.
#define float64 double
#define float32 float
// Some old C++ compilers didn't have bool type
// If your compiler does not have bool then add   emulate_bool
// to your command line -D option or defined macros.
#ifdef emulate_bool
#   ifdef TVISION
#     define bool int
#     define true 1
#     define false 0
#   else
#     ifdef __BCPLUSPLUS__
      //BC++ bool type not available until 5.0
#        define BI_NO_BOOL
#        include <classlib/defs.h>
#     else
#        define bool int
#        define true 1
#        define false 0
#     endif
#  endif
#endif
#ifdef __BCPLUSPLUS__
#  include <systypes.h>
#else
#  ifdef unix
#     ifdef hpux
#        include <sys/_inttypes.h>
#     endif
#     ifdef sun
#        include <sys/int_types.h>
#     endif
#     ifdef linux
#        include <idna.h>
#     endif
#     define int8 int8_t
#     define uint8 uint8_t
#     define int16 int16_t
#     define int32 int32_t
#     define uint16 uint16_t
#     define uint32 uint32_t
#  else
#     ifdef  _MSC_VER
#        include <BaseTSD.h>
#        define int8 INT8
#        define uint8 UINT8
#        define int16 INT16
#        define int32 INT32
#        define uint16 UINT16
#        define uint32 UINT32
#     else
#        ifndef OWL6
//          OWL version 6 already defines these types
#           define int8 char
#           define uint8 unsigned char
#           ifdef __WIN32_
#              define int16 short int
#              define int32 long
#              define uint16 unsigned short int
#              define uint32 unsigned long
#           else
#              define int16 int
#              define int32 long
#              define uint16 unsigned int
#              define uint32 unsigned long
#           endif
#        endif
#      endif
#  endif
#endif
typedef int8   sint8;
typedef int16  sint16;
typedef int32  sint32;
typedef uint8  nat8;
typedef uint16 nat16;
typedef uint32 nat32;
typedef const char * cASCIIz;    // constant null terminated char array
typedef char *       ASCIIz;     // null terminated char array
#endif
//primitive.h
5 голосов
/ 07 ноября 2008

В большинстве случаев количество байтов и диапазон значений определяется архитектурой ЦП, а не C ++. Тем не менее, C ++ устанавливает минимальные требования, которые Литб объяснил правильно, и Мартин Йорк допустил только несколько ошибок.

Причина, по которой вы не можете использовать int и long взаимозаменяемо, заключается в том, что они не всегда имеют одинаковую длину. C был изобретен на PDP-11, где байт имел 8 битов, int был двумя байтами и мог обрабатываться непосредственно аппаратными инструкциями. Поскольку программистам на C часто требовалась четырехбайтовая арифметика, был изобретен long, и это было четыре байта, обрабатываемые библиотечными функциями. Другие машины имели разные характеристики. Стандарт С наложил некоторые минимальные требования.

4 голосов
/ 01 сентября 2010

Стандарт C ++ говорит так:

3.9.1, §2:

Существует пять типов целых чисел со знаком: "подписанный символ", "короткий int", "int", "long int" и "long long int". В этот список, каждый тип обеспечивает как минимум столько памяти, сколько предшествующих в списке. Простые интты имеют натуральный размер, предложенный архитектура исполнения окружающая среда (44); другой подписал целые типы предоставляются для удовлетворения особые потребности.

(44), то есть достаточно большой, чтобы вместить любое значение в диапазоне INT_MIN и INT_MAX, как определено в заголовке <climits>.

Вывод: это зависит от архитектуры, над которой вы работаете. Любое другое предположение неверно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...