C ++中的int和long之间有什么区别?


120

如果我错了请纠正我,

int是4个字节,取值范围是-2,147,483,648至2,147,483,647(2 ^ 31)
长是4个字节,取值范围是-2,147,483,648至2,147,483,647(2 ^ 31)

C ++有什么区别?它们可以互换使用吗?


在运行于32位处理器上的VS2005中,int的默认大小为4字节。


如果您想编写可移植的代码,请考虑使用#include <stdint.h>,然后考虑表明大小的类型。例如uint32_t。在新平台上,您只需要确保stdint.h适用于该特定平台即可,并且您的代码可以按预期工作。
BitTickler 2014年

Answers:


112

它取决于实现。

例如,在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  

我认为我们应该考虑将此答案(示例答案)与以下有关C ++标准的一些细节结合起来。C ++ 0x的草案位于open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf,并且已进行了标记,因此您可以看到它与上次修订版之间的区别。
Patrick Johnmeyer

包括按类型的相对大小顺序排列的内容比枚举不同平台的大小会产生更多的信息-例如@Kevin这样很好。(-1vote)
xtofl,

2
某些编译器甚至具有标志,允许您修改int和long的默认大小,即将它们强制设置为8或16等。有关详细信息,请参见编译器文档。
马丁·约克

7
注意,这些都是
rogerdpack 2010年

1
请同时包含int的大小。
cegprakash 2014年

82

您唯一的保证是:

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


1
嗯,这不成立,如果sizeof(short)> = sizeof(char),我们只知道sizeof(short)> = 1(不是> = 2),这对所有类型都适用。根据这个sizeof(任何整数类型)> =1。这是正确的,例如,我记得Z80上的sizeof(int)== 1,但是长期没有更好的保证吗?
Andreas Magnusson,

6
C ++标准的3.9.1.2指定sizeof(long)> = sizeof(int)> = sizeof(short)> = sizeof(char)C ++标准的5.3.3.1指定sizeof(char),sizeof(unsigned char) ,且sizeof(signed char)等于1。(续...)
KTC

4
(... cont)整数类型可表示的最大值和最小值在<limits.h>中定义为宏(因此在<climits>中)。C(1990)标准的附录E(通过引用包含在C ++标准中)指定了这些宏的最小大小。(续...)
KTC

4
(... cont),它们分别为(2 ^ 15)-1,(2 ^ 15)-1,(2 ^ 31)-1,分别表示short,int和long,它们的值分别为如果CHAR_BIT为8(也是最小值),则由Martin York在其响应中发布。
KTC

2
@吉尔斯:这不是我上面所说的吗?sizeof(short)* CHAR_BITS> =16。还有其他一些事情。:-)
马丁·约克2010年

13

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

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

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


可能是0个字节?嗯
rogerdpack 2015年

12

C ++规范本身(旧版本,但够用了这一点)离开这个开放。

有四种带符号的整数类型:“ signed char”,“ short int”,“ int”和“ long int”。在此列表中,每种类型至少提供与列表中位于其前面的类型一样多的存储。普通整数具有执行环境的架构建议的自然大小*;

[脚注:即,它足够大以包含在header中定义的INT_MIN和INT_MAX范围内的任何值<climits>。---结束foonote]


7

正如Kevin Haines指出的那样,int具有执行环境建议的自然大小,必须适合INT_MIN和INT_MAX。

C89标准规定UINT_MAX应至少为2 ^ 16-1、2 USHRT_MAX^ 16-1和ULONG_MAX2 ^ 32-1。这使得short和int的位数至少为16,而long的位数至少为32。对于char,它明确指出应至少具有8位(CHAR_BIT)。C ++继承了limits.h文件的这些规则,因此在C ++中,我们对这些值具有相同的基本要求。但是,您应该派生从这个int至少为2个字节。从理论上讲,char,int和long都可以是1个字节,在这种情况下CHAR_BIT必须至少为32个字节。请记住,“ byte”始终是char的大小,因此,如果char较大,则字节不仅是8位,而且更多。


我不认为byteC ++中存在数据类型。不是吗?如果是这样,并且a byte可以具有8位以外的其他大小,那纯粹是愚蠢的。除非绝对必须为8位,否则为什么将其称为字节?
Alderath 2012年


5

在大多数情况下,字节数和值的范围是由CPU的体系结构而不是C ++决定的。但是,C ++设置了最低要求,而litb对此进行了正确解释,而Martin York仅犯了一些错误。

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


5

如果您曾经在另一台计算机体系结构,OS或另一家供应商的编译器上编译代码,那么依靠编译器供应商对基本类型大小的实现会困扰您。

大多数编译器供应商都提供一个头文件,该头文件定义具有显式类型大小的基本类型。当有可能将代码移植到另一个编译器时,应使用这些原始类型(在每个实例中始终将其读取)。例如,大多数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的显式基元类型名称和#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

C99强制要求看起来像int32_t,uint64_t等的typdef由编译器定义,并具有与名称暗示的位数一样多的位。大多数C ++编译器(包括g ++)将允许您在C ++代码中使用这些常量。
rmeador

5

C ++标准说,它是这样的:

3.9.1,§2:

有五种有符号整数类型:“有符号字符”,“ short int”,“ int”,“ long int”和“ long long int”。在此列表中,每种类型至少提供与列表中位于其前面的类型一样多的存储。普通整数具有执行环境的架构所建议的自然大小(44);提供其他有符号整数类型以满足特殊需要。

(44),即足以包含在header中定义的INT_MIN和INT_MAX范围内的任何值 <climits>

结论:这取决于您正在使用的体系结构。任何其他假设都是错误的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.