C++ 标准规定 int、long 类型的大小是多少?

Posted

技术标签:

【中文标题】C++ 标准规定 int、long 类型的大小是多少?【英文标题】:What does the C++ standard state the size of int, long type to be? 【发布时间】:2010-10-10 00:40:40 【问题描述】:

我正在寻找有关基本 C++ 类型大小的详细信息。 我知道这取决于架构(16 位、32 位、64 位)和编译器。

但是 C++ 有什么标准吗?

我在 32 位架构上使用 Visual Studio 2008。这是我得到的:

char  : 1 byte
short : 2 bytes
int   : 4 bytes
long  : 4 bytes
float : 4 bytes
double: 8 bytes

我试图找到可靠的信息,说明charshortintlongdoublefloat(以及我没想到的其他类型)的大小,但没有取得多大成功of) 在不同的架构和编译器下。

【问题讨论】:

@thyrgle 不是出于选择...有太多架构需要支持,因此需要灵活。 见:***.com/questions/271076/… 为什么他们不删除所有模糊类型,并将其标准化为确定的位长度类型,例如int32_t、uint32_t、int64_t 等 @thyrgle 实际上很难标准化这样的事情。与 Java 不同,由于 JVM 的工作方式,这些事情是不变的,C/C++ 本质上必须坚持运行它们的系统,而不需要任何花哨的抽象层(至少不像 Java 那么多)in-之间。如果 int 的大小非常重要,可以使用int16_tint32_tint64_t(如果我没记错的话,需要包含iostream)。这有什么好处 int64_t 在 32 位系统上不应该有问题(但这会影响性能)。 @rbaleksandar 它们实际上是在<cstdint> 中定义的,而不是<iostream> 【参考方案1】:

C++ 标准没有以字节为单位指定整数类型的大小,但它指定了它们必须能够容纳的最小范围。您可以从所需范围推断出最小大小。您可以从中推断出最小大小(以字节为单位)以及 defines the number of bits in a byte 的 CHAR_BIT 宏的值。除了最不起眼的平台之外,它是 8 个,而且不能少于 8 个。

char 的另一个限制是它的大小始终为 1 字节,或 CHAR_BIT 位(因此得名)。这在标准中有明确规定。

C 标准是 C++ 标准的规范性参考,因此即使它没有明确说明这些要求,C++ 也需要最小范围 required by the C standard(第 22 页),即与MSDN 上的数据类型范围相同:

    signed char:-127 到 127(注意,不是 -128 到 127;这适用于 1's-complement 和 sign-and-magnitude 平台) unsigned char:0 到 255 “普通”char:与signed charunsigned char、implementation-defined 相同的范围 signed short:-32767 到 32767 unsigned short: 0 到 65535 signed int:-32767 到 32767 unsigned int: 0 到 65535 signed long: -2147483647 到 2147483647 unsigned long: 0 到 4294967295 signed long long: -9223372036854775807 至 9223372036854775807 unsigned long long:0到18446744073709551615

C++(或C)实现可以将类型的大小(以字节sizeof(type) 为单位)定义为任何值,只要

    表达式sizeof(type) * CHAR_BIT 计算出的位数足够高以包含所需的范围,并且 类型的排序仍然有效(例如sizeof(int) <= sizeof(long))。

综上所述,我们保证:

charsigned charunsigned char 至少为 8 位 signed shortunsigned shortsigned intunsigned int 至少为 16 位 signed longunsigned long 至少为 32 位 signed long longunsigned long long 至少为 64 位

不保证floatdouble 的大小,除非double 提供的精度至少与float 一样高。

可以在 C 中的 <limits.h> 标头或 C++ 中的 <climits> 中找到实际实现特定的范围(或者更好的是,<limits> 标头中的模板化 std::numeric_limits)。

例如,您将通过以下方式找到int 的最大范围:

C:

#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;

C++

#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();

【讨论】:

相反,C++ 标准使用单词 byte 来表示“1 char”,而不是通常的意思。 @Programmer 阅读答案(括号中的第 1 点注释),或实际标准的措辞(链接在答案中)。 C 标准支持 1 的补码体系结构,其表示与最普遍的 2 的补码不同。最小保证范围几乎总是与实现提供的实际范围不同。 @Alex B 您在回答中没有提到任何关于 double 的内容。您能否更新您对浮点变量的答案? @Cool_Coder:浮点是一个额外的鱼缸,很容易使帖子大小翻倍。 请注意,C++20 现在要求有符号整数类型的二进制补码。【参考方案2】:

对于 32 位系统,“事实上的”标准是 ILP32,即intlong 和指针都是 32 位量。

对于 64 位系统,主要的 Unix“事实上的”标准是 LP64 — long 和指针是 64 位(但 int 是 32 位)。 Windows 64 位标准是 LLP64 — long long 和指针是 64 位(但 longint 都是 32 位)。

曾经,一些 Unix 系统使用 ILP64 组织。

这些事实上的标准都不是由 C 标准 (ISO/IEC 9899:1999) 立法规定的,但都是允许的。

根据定义,sizeof(char)1,尽管在 Perl 配置脚本中进行了测试。

请注意,有些机器 (Crays) 的 CHAR_BIT 远大于 8。这意味着,IIRC,sizeof(int) 也是 1,因为 charint 都是 32 位的。

【讨论】:

+1 用于说明在最重要的情况下实际情况如何,而不是理论上的情况。如果你想要 32 位使用 int,如果你想要 64 位使用 long long。如果你想原生使用 size_t。避免“简单”太长,因为它会有所不同。这应该适用于大多数应用程序。 +1 为答案。 @Eloff:相反...如果您想要 32 位使用 [u]int32_t 或类似的,如果您想要 64 位使用 [u]int64_t...如果您没有标题,请下载或制作一个,最好使用此类类型的编译时选择或静态断言来验证大小。 pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html 如果精确的尺寸不是那么重要,而您只关心它们至少有那么大,那么您的建议适用于常见的现代 PC/服务器平台。 请注意,不仅仅是旧的 Cray 机器具有 CHAR_BIT > 8。例如DSP 的 CHAR_BIT 通常为 16 或 32。(参见例如these) @nos:谢谢你的链接。为古怪案件确定现代的、当前的系统是非常有帮助的。出于好奇,这些机器上设置的代码是什么?如果代码集是 UTF-16,那么 0xFFFF 不是有效字符,如果代码集是 ISO 8859-x 代码集,那么 0xFFFF 也是无效字符(从 0x00 到 0xFF 的字符代码是有效的)。我还不相信检测 EOF 有问题,但肯定有谨慎的余地,可能要编写和使用返回 EOF 或 0 并设置 *c 的函数 int get_char(FILE *fp, char *c) @supercat:这样做会使所有整数提升规则失效。向后兼容性意味着在 C 被遗忘之前不太可能发生这种情况,而且目前还看不到。【参考方案3】:

实际上没有这样的事情。通常你可以期望std::size_t 代表当前架构上的无符号本机整数大小。即 16 位、32 位或 64 位,但并非总是如此,正如 cmets 对此答案所指出的那样。

就所有其他内置类型而言,它实际上取决于编译器。以下是从最新 C++ 标准的当前工作草案中摘录的两段:

有五种标准有符号整数类型:signed char、short int、int、long int 和 long long int。在此列表中,每种类型提供的存储空间至少与列表中它前面的类型一样多。

对于每一种标准的有符号整数类型,都存在对应的(但不同的)标准无符号整数类型:unsigned char、unsigned short int、unsigned int、unsigned long int和unsigned long long int,每一种都占相同的存储量和相同的对齐要求。

如果你愿意,你可以静态地(编译时)断言这些基本类型的大小。如果 sizeof 假设发生变化,它将提醒人们考虑移植您的代码。

【讨论】:

好帖子。需要的另一件事是以下最小位大小(在 c89 / c99 中与 limits.h 一起记录并由 c++ 接管): char >=8, short and int >=16, long >=32 。 另外,在 8 位 AVR 平台上 size_t 不会是 8 位,而是 16 位,因为指针和 int 大小都是 16 位。所以处理器原生数据大小与size_t无关。【参考方案4】:

有标准。

C90 标准要求

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

C99 标准要求

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

Here is the C99 specifications。第 22 页详细介绍了不同整数类型的大小。

这是 Windows 平台的 int 类型大小(位):

Type           C99 Minimum     Windows 32bit
char           8               8
short          16              16
int            16              32
long           32              32
long long      64              64

如果您关心可移植性,或者您希望类型的名称反映大小,您可以查看标题&lt;inttypes.h&gt;,其中可以使用以下宏:

int8_t
int16_t
int32_t
int64_t

int8_t保证8位,int16_t保证16位,以此类推

【讨论】:

次要挑剔:标准在哪里说 sizeof(long) &lt; sizeof(long long) 而不是对称的 sizeof(long) &lt;= sizeof(long long) @JonathonLeffler - 参见 C99 5.2.4.2.1 - 整数类型的大小。 minsizeof(int)==16 位,minsizeof(long)==32 位,minsizeof(long long)==64 位。所以我认为你在 类似地 sizeof(float) 【参考方案5】:

如果您需要固定大小的类型,请使用 stdint.h 中定义的类型,如 uint32_t(无符号整数 32 位)。它们在C99 中指定。

【讨论】:

它们是指定的,但不是必需的。 @dreamlax 哪些平台不包含它? @LeviMorrison:任何没有所需形式的平台。例如,具有CHAR_BIT == 16 的平台不会具有int8_t。任何不使用补码的平台都不会有任何(因为标准要求补码)。 @DevSolar:我想知道 C99 标准的作者是否打算禁止具有 16 位无符号类型的实现定义 uint16_t,除非它们还具有带范围的二进制补码类型 - 32768 至 32767(含)。我认为如果一个实现的 16 位有符号整数类型不满足要求(很可能是因为位模式 0x8000 并不总是像紧邻 -32767 的整数值那样表现),那么让它定义 @987654326 会更有用@ 没有定义int16_t,而不是禁止它声明。【参考方案6】:

更新:C++11 将 TR1 中的类型正式纳入标准:

long long int unsigned long long int

还有来自&lt;cstdint&gt;的“大小”类型

int8_t int16_t int32_t int64_t (以及未签名的对应物)。

另外你得到:

int_least8_t int_least16_t int_least32_t int_least64_t 加上未签名的对应物。

这些类型表示具有至少指定位数的最小整数类型。同样,有至少指定位数的“最快”整数类型:

int_fast8_t int_fast16_t int_fast32_t int_fast64_t 加上未签名的版本。

“快速”的含义(如果有的话)取决于实施。对于所有目的,它也不必是最快的。

【讨论】:

这是 C++11 标准的一部分。 “快”仅仅意味着为硬件架构量身定制。如果寄存器为 16 位,则 int_fast8_t 为 16 位值。如果寄存器是 32 位的,那么 int_fast8_t 和 int_fast16_t 都是 32 位的值。等见 C99 第 7.18.1.3 节第 2 段。【参考方案7】:

C++ Standard 是这样说的:

3.9.1,§2:

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

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

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

【讨论】:

【参考方案8】:

不,字体大小没有标准。标准只要求:

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

如果您想要固定大小的变量,最好的办法是使用这样的宏:

#ifdef SYSTEM_X
  #define WORD int
#else
  #define WORD long int
#endif

然后您可以使用 WORD 来定义您的变量。不是我喜欢这种方式,而是最便携的方式。

【讨论】:

问题是 WORD 在程序中传播到不真正依赖于固定大小的区域(查看一些 Windows 代码)。正如我在从 16 位系统迁移到 32 位系统时发现的那样,最终会遇到与 WORD 相同的问题。 @liburne 当然,只有在需要固定大小的变量时才应该使用 WORD,例如在读取/写入文件时。如果一段代码不是真正依赖于固定大小,那么您应该使用普通的“int”变量。 获得便携尺寸的最佳方法应该是#include &lt;boost/cstdint.hpp&gt;【参考方案9】:

对于浮点数there is a standard (IEEE754):浮点数是 32 位,双精度数是 64。这是硬件标准,而不是 C++ 标准,因此编译器理论上可以将浮点数和双精度数定义为其他大小,但实际上我已经从未见过使用任何不同的架构。

【讨论】:

但是,在 C++ 中是否符合 IEEE 754(又名 IEC 559)是可选的(可能也是 C,但我不确定)。见 std::numeric_limits::is_iec559。 那么您还没有看到 TI 的 TMS320C28xx DSP 编译器,其中double 的大小与float 相同(而intchar 相同,均为16 位)。但他们有一个 64 位的long double【参考方案10】:

我们可以为该类型定义同义词,这样我们就可以创建自己的“标准”。

在 sizeof(int) == 4 的机器上,我们可以定义:

typedef int int32;

int32 i;
int32 j;
...

因此,当我们将代码转移到实际上 long int 的大小为 4 的另一台机器上时,我们可以重新定义 int 的单次出现。

typedef long int int32;

int32 i;
int32 j;
...

【讨论】:

鉴于标准头文件 &lt;stdint.h&gt;(C99 及更高版本,以及采用 C99 版本的 C 库的任何 C++ 标准),这不是必需的。【参考方案11】:

有一个标准,它在各种标准文档(ISO、ANSI 等)中都有规定。

***有一个很棒的页面解释了各种类型和它们可以存储的最大值: Integer in Computer Science.

但是,即使使用标准 C++ 编译器,您也可以使用以下代码 sn-p 相对容易地找到:

#include <iostream>
#include <limits>


int main() 
    // Change the template parameter to the various different types.
    std::cout << std::numeric_limits<int>::max() << std::endl;

std::numeric_limits 的文档可以在Roguewave 找到。它包括大量其他命令,您可以调用它来找出各种限制。这可以与任何传达大小的任意类型一起使用,例如 std::streamsize。

约翰的回答包含最好的描述,因为这些是保证成立的。无论您在哪个平台上,还有一个很好的页面,其中详细介绍了每种类型必须包含多少位:int types,在标准中定义。

我希望这会有所帮助!

【讨论】:

【参考方案12】:

当涉及到不同架构和不同编译器的内置类型时,只需使用编译器在您的架构上运行以下代码即可查看它的输出。下面显示了我的Ubuntu 13.04 (Raring Ringtail) 64 位 g++4.7.3 输出。另请注意以下回答的内容,这就是输出如此排序的原因:

“有五种标准有符号整数类型:signed char、short int、int、long int 和 long long int。在此列表中,每种类型提供的存储空间至少与列表中它前面的类型一样多。”

#include <iostream>

int main ( int argc, char * argv[] )

  std::cout<< "size of char: " << sizeof (char) << std::endl;
  std::cout<< "size of short: " << sizeof (short) << std::endl;
  std::cout<< "size of int: " << sizeof (int) << std::endl;
  std::cout<< "size of long: " << sizeof (long) << std::endl;
  std::cout<< "size of long long: " << sizeof (long long) << std::endl;

  std::cout<< "size of float: " << sizeof (float) << std::endl;
  std::cout<< "size of double: " << sizeof (double) << std::endl;

  std::cout<< "size of pointer: " << sizeof (int *) << std::endl;



size of char: 1
size of short: 2
size of int: 4
size of long: 8
size of long long: 8
size of float: 4
size of double: 8
size of pointer: 8

【讨论】:

sizeof(char) 不应包含在内。【参考方案13】:

1) 文章“The forgotten problems of 64-bit programs development”中的表 N1

2) "Data model"

【讨论】:

【参考方案14】:

你可以使用:

cout << "size of datatype = " << sizeof(datatype) << endl;

datatype = intlong int 等。 您将能够看到您键入的任何数据类型的大小。

【讨论】:

【参考方案15】:

如前所述,大小应反映当前架构。如果你想看看你当前的编译器是如何处理事情的,你可以在limits.h 中找到一个高峰。

【讨论】:

谢谢,但我想知道我自己没有的架构的大小(比如 64 位)。本教程只讨论 32 位架构...【参考方案16】:

如果您对纯 C++ 解决方案感兴趣,我使用模板和仅 C++ 标准代码在编译时根据它们的位大小定义类型。 这使得解决方案可跨编译器移植。

背后的想法很简单:创建一个包含 char、int、short、long、long long 类型(有符号和无符号版本)的列表,然后扫描列表并使用 numeric_limits 模板选择给定大小的类型。

包含此标头,您将获得 8 种类型 stdtype::int8、stdtype::int16、stdtype::int32、stdtype::int64、stdtype::uint8、stdtype::uint16、stdtype::uint32、stdtype::uint64。

如果某些类型无法表示,它将被评估为同样在该标头中声明的 stdtype::null_type。

以下代码不提供任何保证,请仔细检查。 我也是元编程新手,请随意编辑和更正此代码。 用 DevC++ 测试(所以 gcc 版本在 3.5 左右)

#include <limits>

namespace stdtype

    using namespace std;


    /*
     * THIS IS THE CLASS USED TO SEMANTICALLY SPECIFY A NULL TYPE.
     * YOU CAN USE WHATEVER YOU WANT AND EVEN DRIVE A COMPILE ERROR IF IT IS 
     * DECLARED/USED.
     *
     * PLEASE NOTE that C++ std define sizeof of an empty class to be 1.
     */
    class null_type;

    /*
     *  Template for creating lists of types
     *
     *  T is type to hold
     *  S is the next type_list<T,S> type
     *
     *  Example:
     *   Creating a list with type int and char: 
     *      typedef type_list<int, type_list<char> > test;
     *      test::value         //int
     *      test::next::value   //char
     */
    template <typename T, typename S> struct type_list
    
        typedef T value;
        typedef S next;         

    ;




    /*
     * Declaration of template struct for selecting a type from the list
     */
    template <typename list, int b, int ctl> struct select_type;


    /*
     * Find a type with specified "b" bit in list "list"
     *
     * 
     */
    template <typename list, int b> struct find_type
       
        private:
            //Handy name for the type at the head of the list
            typedef typename list::value cur_type;

            //Number of bits of the type at the head
            //CHANGE THIS (compile time) exp TO USE ANOTHER TYPE LEN COMPUTING
            enum cur_type_bits = numeric_limits<cur_type>::digits;

        public:
            //Select the type at the head if b == cur_type_bits else
            //select_type call find_type with list::next
            typedef  typename select_type<list, b, cur_type_bits>::type type;
    ;

    /*
     * This is the specialization for empty list, return the null_type
     * OVVERRIDE this struct to ADD CUSTOM BEHAVIOR for the TYPE NOT FOUND case
     * (ie search for type with 17 bits on common archs)
     */
    template <int b> struct find_type<null_type, b>
       
        typedef null_type type;

    ;


    /*
     * Primary template for selecting the type at the head of the list if
     * it matches the requested bits (b == ctl)
     *
     * If b == ctl the partial specified templated is evaluated so here we have
     * b != ctl. We call find_type on the next element of the list
     */
    template <typename list, int b, int ctl> struct select_type
       
            typedef  typename find_type<typename list::next, b>::type type; 
    ;

    /*
     * This partial specified templated is used to select top type of a list
     * it is called by find_type with the list of value (consumed at each call)
     * the bits requested (b) and the current type (top type) length in bits
     *
     * We specialice the b == ctl case
     */
    template <typename list, int b> struct select_type<list, b, b>
    
            typedef typename list::value type;
    ;


    /*
     * These are the types list, to avoid possible ambiguity (some weird archs)
     * we kept signed and unsigned separated
     */

    #define UNSIGNED_TYPES type_list<unsigned char,         \
        type_list<unsigned short,                           \
        type_list<unsigned int,                             \
        type_list<unsigned long,                            \
        type_list<unsigned long long, null_type> > > > >

    #define SIGNED_TYPES type_list<signed char,         \
        type_list<signed short,                         \
        type_list<signed int,                           \
        type_list<signed long,                          \
        type_list<signed long long, null_type> > > > >



    /*
     * These are acutally typedef used in programs.
     * 
     * Nomenclature is [u]intN where u if present means unsigned, N is the 
     * number of bits in the integer
     *
     * find_type is used simply by giving first a type_list then the number of 
     * bits to search for.
     *
     * NB. Each type in the type list must had specified the template 
     * numeric_limits as it is used to compute the type len in (binary) digit.
     */
    typedef find_type<UNSIGNED_TYPES, 8>::type  uint8;
    typedef find_type<UNSIGNED_TYPES, 16>::type uint16;
    typedef find_type<UNSIGNED_TYPES, 32>::type uint32;
    typedef find_type<UNSIGNED_TYPES, 64>::type uint64;

    typedef find_type<SIGNED_TYPES, 7>::type    int8;
    typedef find_type<SIGNED_TYPES, 15>::type   int16;
    typedef find_type<SIGNED_TYPES, 31>::type   int32;
    typedef find_type<SIGNED_TYPES, 63>::type   int64;


【讨论】:

【参考方案17】:

正如其他人回答的那样,“标准”将大部分细节都保留为“实现定义”,并且仅声明“char”类型至少为“char_bis”宽,并且“char

没有非常具体和精确的值的部分原因是因为像 C/C++ 这样的语言被设计为可移植到大量硬件平台——包括“char”字长可能是4 位或 7 位,甚至是普通家庭计算机用户所接触的“8 位/16 位/32 位/64 位”计算机之外的某个值。 (这里的字长是指系统正常运行的位宽——同样,它并不总是像家庭计算机用户所期望的那样总是 8 位。)

如果您确实需要特定位数的对象(在表示整数值的一系列位的意义上),大多数编译器都有一些指定方法;但它通常不可移植,即使在 ame 公司制造但针对不同平台的编译器之间也是如此。一些标准和实践(尤其是 limits.h 等)非常普遍,以至于大多数编译器都支持确定特定值范围的最佳拟合类型,但不支持确定使用的位数。 (也就是说,如果您知道您需要保存 0 到 127 之间的值,您可以确定您的编译器支持 8 位的“int8”类型,它足以容纳所需的全部范围,但不像"int7" 类型,这将与 7 位完全匹配。)

注意:许多 Un*x 源代码包使用“./configure”脚本,该脚本将探测编译器/系统的功能并输出合适的 Makefile 和 config.h。您可以检查其中一些脚本以了解它们是如何工作的以及它们如何探测编译器/系统功能,并遵循它们的指导。

【讨论】:

AFAIK 标准要求 CHAR_BITS 至少为 8,因此 C++ 无法操作没有填充的 7 位整数。 诚然,我一直没有跟上当前的标准。但是,我在 1980 年代末/1990 年代初学习了 C,当时“标准”仍在从 K&R 的定义演变而来,并且没有由有组织的标准机构在国际上定义。 7 位计算已经被淘汰和过时,主要只出现在 7 位“文本模式”FTP 等遗留应用程序中。然而,K&R C 已经成立,需要继续弥合这一差距。到 C99 获得批准时,世界已经是 8 位和 16 位,32 位计算正在迅速普及。【参考方案18】:

我注意到这里所有其他答案几乎都集中在整数类型上,而提问者还询问了浮点数。

我不认为 C++ 标准需要它,但现在最常见平台的编译器通常遵循 IEEE754 标准的浮点数。该标准指定了四种类型的二进制浮点(以及一些 BCD 格式,我从未见过 C++ 编译器支持这些格式):

半精度(二进制 16)- 11 位有效数,指数范围 -14 到 15 单精度 (binary32) - 24 位有效数,指数范围 -126 到 127 双精度 (binary64) - 53 位有效数,指数范围 -1022 到 1023 四倍精度 (binary128) - 113 位有效数,指数范围 -16382 到 16383

那么,它是如何映射到 C++ 类型的呢?一般float 使用单精度;因此,sizeof(float) = 4。然后double 使用双精度(我相信这是名称double 的来源),而long double 可能是双精度或四精度(在我的系统上是四精度,但在32 位系统上可能是双精度) .我不知道任何提供半精度浮点的编译器。

总而言之,这是通常的情况:

sizeof(float) = 4 sizeof(double) = 8 sizeof(long double) = 8 或 16

【讨论】:

有趣的是,我提出这个问题是想知道为什么 Jeff 使用的字节数比他需要的多。【参考方案19】:
unsigned char bits = sizeof(X) << 3;

其中Xcharintlong 等。将为您提供X 的大小(以位为单位)。

【讨论】:

a char 并不总是 8 位,因此您的表达式不适用于 architectures with non-8-bit char。只有sizeof(type)*CHAR_BIT 持有 即使CHAR_BIT被保证为8位,&lt;&lt; 3也只是* 8* CHAR_BIT的一种混淆方式。【参考方案20】:

来自 Alex B C++ 标准没有以字节为单位指定整数类型的大小,但它指定了它们必须能够容纳的最小范围。您可以从所需范围推断出最小大小。您可以从中推断出以字节为单位的最小大小,以及定义字节中位数的 CHAR_BIT 宏的值(除了最晦涩的平台,它是 8,并且不能小于 8)。

char 的另一个限制是它的大小始终为 1 个字节,或 CHAR_BIT 位(因此得名)。

标准要求的最小范围(第 22 页)是:

和 MSDN 上的数据类型范围:

signed char:-127 到 127(注意,不是 -128 到 127;这适用于 1 的补码平台) 无符号字符:0 到 255 “plain” char:-127 到 127 或 0 到 255(取决于默认的 char 符号) 签名短:-32767 到 32767 无符号短:0 到 65535 有符号整数:-32767 到 32767 无符号整数:0 到 65535 长签名:-2147483647 到 2147483647 无符号长:0 到 4294967295 签名长长:-9223372036854775807 至 9223372036854775807 unsigned long long: 0 到 18446744073709551615 C++(或 C)实现可以将类型的大小(以字节 sizeof(type) 为单位)定义为任何值,只要

表达式 sizeof(type) * CHAR_BIT 计算为足以包含所需范围的位数,并且 类型的排序仍然有效(例如 sizeof(int)

例如,您将通过以下方式找到 int 的最大范围:

C:

#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;

C++:

#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();

这是正确的,但是,您也说对了: 字符:1 字节 短:2字节 整数:4 个字节 长:4 个字节 浮动:4字节 双倍:8 个字节

因为 32 位架构仍然是默认和最常用的架构,并且自 32 位之前的可用内存较少时以来,它们一直保持这些标准大小,并且为了向后兼容和标准化,它保持不变。甚至 64 位系统也倾向于使用这些并进行扩展/修改。 更多信息请参考:

http://en.cppreference.com/w/cpp/language/types

【讨论】:

我不知道这如何为Alex's answer 增加任何内容,这是在此之前 6 年提供的?【参考方案21】:

正如您所提到的 - 这在很大程度上取决于编译器和平台。为此,请检查 ANSI 标准,http://home.att.net/~jackklein/c/inttypes.html

这是用于 Microsoft 编译器的那个:Data Type Ranges

【讨论】:

【参考方案22】:

可以使用OpenGL、Qt等库提供的变量

例如Qtprovidesqint8(Qt支持的所有平台保证8位)、qint16、qint32、qint64、quint8、quint16、quint32、quint64等

【讨论】:

不回答问题【参考方案23】:

在 64 位机器上:

int: 4
long: 8
long long: 8
void*: 8
size_t: 8

【讨论】:

在某些 64 位机器上int 是 8 个字节,但另一个不保证。没有什么说 char 应该只有 8 位。 sizeof(void*)==4 是允许的,即使它是 64 位。【参考方案24】:

根据大小有四种类型的整数:

短整数:2字节 长整数:4字节 long long integer:8字节 整数:取决于编译器(16 位、32 位或 64 位)

【讨论】:

错误,它们都依赖于架构,在其他答案之一中描述了最小范围。没有什么能阻止实现具有 shortintlong 所有 32 位整数。 您甚至没有使用正确的类型名称。这些名称使用关键字int,而不是“整数”一词。

以上是关于C++ 标准规定 int、long 类型的大小是多少?的主要内容,如果未能解决你的问题,请参考以下文章

关于C++算术类型

C++ short/int/long/long long 等数据类型大小

转帖不同平台数据类型的大小

c++中,long long是啥类型?

long类型数字的范围是多大啊?

请教在C++里如何把string类型转换成long型?