【问题标题】:What is the difference between an int and a long in C++?C++ 中的 int 和 long 有什么区别?
【发布时间】:2023-03-14 01:39:01
【问题描述】:

如果我错了,请纠正我,

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++ 有什么不同?它们可以互换使用吗?

【问题讨论】:

  • 在我的32位处理器上运行的VS2005中,int的默认大小是4字节。
  • 如果你想编写可移植的代码,请考虑使用#include <stdint.h>,然后使用说明大小的类型。例如。 uint32_t。在新平台上,您只需确保 stdint.h 适合该特定平台并且您的代码按预期工作。

标签: c++ variables


【解决方案1】:

它取决于实现。

例如,在 Windows 下它们是相同的,但例如在 Alpha 系统上,long 是 64 位,而 int 是 32 位。这个article 涵盖了英特尔 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,并已标记,因此您可以看到它与上一版之间的差异。
  • 在类型的相对大小顺序上包含一些东西比枚举不同平台的大小产生更多的信息——比如@Kevin 状态很好。 (-1 票)
  • 一些编译器甚至具有允许您修改 int 和 long 的默认大小的标志,即强制它们为 8 或 16 等。有关详细信息,请参阅编译器文档。
  • 注意这些是 long 的尺寸
  • 请同时包含 int 的大小。
【解决方案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

另见:Is long guaranteed to be at least 32 bits?

【讨论】:

  • 嗯,这不成立,如果 sizeof(short) >= sizeof(char) 我们只知道 sizeof(short) >= 1(不是 >= 2),顺便说一句,这适用于所有人的类型。根据这个 sizeof(any integer type) >= 1。这是真的,例如我记得Z80上的sizeof(int) == 1,但是长期没有更强的保证吗?
  • 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。(续...)
  • (...cont) 整数类型可表示的最大值和最小值在 中定义为宏(因此是 )。 C (1990) 标准的附录 E(通过引用从 C++ 标准中包含在内)指定了这些宏的最小幅度。 (续...)
  • (...cont) 它们分别是 (2^15)-1, (2^15)-1, (2^31)-1, 分别是short, int, and long,如果 CHAR_BIT 为 8(这也是它的最小值),那么这就是 Martin York 在他的回复中发布的值。
  • @Giles:这不是我上面说的吗? sizeof(short) * CHAR_BITS >= 16。加上其他一些东西。 :-)
【解决方案3】:

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

GCC 使用的是 LP64 模型,也就是说 int 是 32 位,而 long 在 64 位模式下是 64 位。

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

【讨论】:

  • 可能是 0 字节?嗯
【解决方案4】:

C++ specification itself(旧版本,但足够好)保持开放状态。

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

[脚注:也就是说,大到足以 包含范围内的任何值 INT_MIN 和 INT_MAX,如 标头&lt;climits&gt;。 --- 结束脚注]

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

    • 我认为 C++ 中不存在 byte 数据类型。它没有,是吗?如果是这样,并且 byte 可以有 8 位以外的其他大小,那就太愚蠢了。除非绝对必须是 8 位,否则他们为什么称它为字节?
    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

        依赖于编译器供应商对原始类型大小的实现 如果你曾经在另一个上编译你的代码,会回来困扰你 机器架构、操作系统或其他供应商的编译器。

        大多数编译器供应商都提供了一个头文件,用于定义基本类型 显式类型大小。 当代码可能被移植时,应该使用这些原始类型 到另一个编译器(在每个实例中都将其读取为始终)。 例如,大多数 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++ 代码中使用这些常量。
        【解决方案9】:

        C++ Standard 是这样说的:

        3.9.1,第 2 节:

        有五种有符号整数类型: “有符号字符”、“短整数”、“整数”、 “long int”和“long long int”。在 此列表中,每种类型至少提供 与其前面一样多的存储空间 在列表中。普通整数有 建议的自然尺寸 执行架构 环境 (44);另一个签名 提供整数类型以满足 特殊需要。

        (44) 即 大到足以容纳 INT_MIN 范围内的任何值和 INT_MAX,在标题中定义 &lt;climits&gt;.

        结论:这取决于您正在处理的架构。任何其他假设都是错误的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-13
          • 2010-12-27
          • 1970-01-01
          • 2010-09-12
          相关资源
          最近更新 更多