В чем разница между int и long на С++?

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

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

В чем разница в С++? Можно ли их использовать взаимозаменяемо?

Ответ 1

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

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

  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  

Ответ 2

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

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 битами?

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

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

В течение многих лет я использовал явные примитивные имена Borland и #include следующий заголовочный файл C/С++ (primitive.h) который предназначен для определения явных примитивных типов с этими именами для любого компилятора 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

Ответ 9

С++ Standard говорит следующее:

3.9.1, §2:

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

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

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