在C++中,int和long有什么区别

What is the difference between an int and a long in C++?

本文关键字:long 什么 区别 int C++      更新时间:2023-10-16

如果我错了,请纠正我,

int是4个字节,值的范围从-2147483648到2147483647(2^31)
long是4个字节,取值范围从-2147483648到2147483647(2^31)

C++有什么不同?它们可以互换使用吗?

它依赖于实现。

例如,在Windows下,它们是相同的,但例如在Alpha系统上,long是64位,而int是32位。本文介绍在可变平台上使用英特尔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  

您唯一的保证是:

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位?

为x64编译时,int和long之间的差异在0到4字节之间,具体取决于您使用的编译器。

GCC使用LP64模型,这意味着int是32位,但在64位模式下long是64位。

例如,MSVC使用LLP64模型,这意味着即使在64位模式下,int和long都是32位。

C++规范本身(旧版本,但足够好)保留了这一点。

有四种带符号整数类型:‘signed char’、‘short int’,‘int’和‘long int’。在这个列表,每种类型至少提供与之前的存储空间一样多列表。普通int具有天然的架构建议的大小执行环境*;

[脚注:即足够大包含范围内的任何值INT_MIN和INT_MAX,如标题<climits>.---end foonote]

Kevin Haines指出,INT具有执行环境建议的自然大小,必须适合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++继承了limites.h文件的那些规则,因此在C++中,我们对这些值有相同的基本要求。然而,您应该而不是从int至少为2字节的条件派生。理论上,char、int和long都可以是1个字节,在这种情况下CHAR_BIT必须至少是32。请记住,"字节"总是一个字符的大小,所以如果字符更大,一个字节就不再只有8位了。

这取决于您的编译器。可以保证一个long至少和int一样大,但不能保证它会更长。

在大多数情况下,字节数和值的范围由CPU的体系结构决定,而不是由C++决定。然而,C++设置了最低要求,litb对此解释得很好,Martin York只犯了几个错误。

不能互换使用int和long的原因是它们的长度并不总是相同的。C是在PDP-11上发明的,其中一个字节有8位,int是两个字节,可以直接由硬件指令处理。由于C程序员经常需要四字节的算术运算,long被发明了,它是四字节的,由库函数处理。其他机器有不同的规格。C标准规定了一些最低要求。

依赖编译器供应商对基元类型大小的实现如果你在另一个平台上编译代码,它会再次困扰你机器体系结构、操作系统或其他供应商的编译器。

大多数编译器供应商提供的头文件定义基元类型显式类型大小。当可能移植代码时,应该使用这些基元类型到另一个编译器(在每个实例中读取为ALWAYS)。例如,大多数UNIX编译器都有int8_t uint8_t int16_t int32_t uint32_t。微软有INT8 UINT8 INT16 UINT16 INT32 UINT32。我更喜欢Borland/CodeGear的int8 uint8 int16 uint16 int32 uint32。这些名称也会提醒您预期值的大小/范围。

多年来,我一直使用Borland的显式原始类型名称以及CCD_ 15下面的C/C++头文件(原语.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

C++标准是这样说的:

3.9.1,§2:

有五种带符号整数类型:"signed char","short int","int","long-int"answers"long-long-int"。在里面该列表中,每种类型至少提供与之前的存储空间一样多在列表中。普通int具有建议的自然尺寸执行体系结构环境(44);另一个签名提供整数类型以满足特殊需要。

(44)也就是说,大到足以容纳INT_MIN和INT_MAX,如标题中所定义<climits>

结论是:这取决于你所使用的架构。任何其他假设都是错误的。