ChatGPT解决这个技术问题 Extra ChatGPT

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

我正在寻找有关基本 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(以及我没有想到的其他类型)大小的可靠信息,但没有取得多大成功不同的架构和编译器。

@thyrgle 不是出于选择...有太多架构需要支持,它需要灵活。
他们为什么不删除所有模糊的类型,并将其全部标准化为确定的位长度类型,例如 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> 中。

C
Community

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

char 的另一个约束是它的大小始终为 1 字节或 CHAR_BIT 位(因此得名)。这在标准中明确说明。

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

有符号字符:-127 到 127(注意,不是 -128 到 127;这适用于 1 的补码和符号和幅度平台) 无符号字符:0 到 255 “普通”字符:与有符号字符或无符号字符的范围相同,实现-defined signed short: -32767 to 32767 unsigned short: 0 to 65535 signed int: -32767 to 32767 unsigned int: 0 to 65535 signed long: -2147483647 to 2147483647 unsigned long: 0 to 4294967295 signed long long: -9223372036854775807 to 9223372036854775807 unsigned长长:0到18446744073709551615

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

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

综上所述,我们保证:

char、signed char 和 unsigned char 至少为 8 位

有符号短、无符号短、有符号整数和无符号整数至少为 16 位

signed long 和 unsigned long 至少为 32 位

signed long long 和 unsigned 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 现在要求有符号整数类型的二进制补码。
J
Jonathan Leffler

对于 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 被遗忘之前不太可能发生这种情况,而且目前还看不到。
C
Community

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

就所有其他内置类型而言,它实际上取决于编译器。以下是从最新 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 和 int >=16, long >=32 。
此外,在 8 位 AVR 平台上 size_t 不会是 8 位,而是 16 位,因为指针和 int 大小是 16 位。因此处理器本机数据大小与 size_t 无关。
M
Mooing Duck

有标准。

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

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

int8_t
int16_t
int32_t
int64_t

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


轻微的挑剔:标准在哪里说 sizeof(long) < sizeof(long long) 而不是对称的 sizeof(long) <= sizeof(long long)
@JonathonLeffler - 参见 C99 5.2.4.2.1 - 整数类型的大小。 minsizeof(int)==16 位,minsizeof(long)==32 位,minsizeof(long long)==64 位。所以我认为你在 <= 上是对的,因为没有指定 maxsizeof(type) 。
同样 sizeof(float) <= sizeof(double) <= sizeof(long double)。根据 C99 7.12 第 2 段。
P
Peter Mortensen

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


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

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

长长整数

unsigned long long int

以及 <cstdint> 中的“大小”类型

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 段。
P
Peter Mortensen

C++ Standard 是这样说的:

3.9.1,§2:

有五种有符号整数类型:“signed char”、“short int”、“int”、“long int”和“long long int”。在此列表中,每种类型提供的存储空间至少与列表中它前面的类型一样多。普通整数具有执行环境架构所建议的自然大小(44);提供其他有符号整数类型以满足特殊需要。 (44) 即大到足以包含 INT_MIN 和 INT_MAX 范围内的任何值,如标题 中所定义。

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


E
Emiliano

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

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 <boost/cstdint.hpp>
C
Crashworks

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


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

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

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

typedef int int32;

int32 i;
int32 j;
...

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

typedef long int int32;

int32 i;
int32 j;
...

鉴于标准头文件 <stdint.h>(C99 及更高版本,以及采用 C99 版本的 C 库的任何 C++ 标准),这不是必需的。
X
X-Istence

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

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

然而,即使使用标准 C++ 编译器,您也可以使用以下代码片段相对轻松地找到:

#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,在标准中定义。

我希望这有帮助!


P
Peter Mortensen

当涉及到不同架构和不同编译器的内置类型时,只需使用编译器在您的架构上运行以下代码以查看它的输出。下面显示了我的 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) 不应包含在内。
佚名
H
Hanky Panky

您可以使用:

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

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


R
Rohit Vipin Mathews

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


谢谢,但我想知道我自己没有的架构的大小(比如 64 位)。本教程只讨论 32 位架构...
u
user781847

如果您对纯 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;

}

C
C. M.

正如其他人所回答的那样,“标准”将大部分细节都保留为“实现定义”,并且仅声明“char”类型至少为“char_bis”宽,并且“char <= short <= int <= long < = long long”(float 和 double 与 IEEE 浮点标准非常一致,long double 通常与 double 相同——但在更多当前的实现中可能更大)。

没有非常具体和精确的值的部分原因是因为像 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 位计算正在迅速普及。
c
celticminstrel

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

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

半精度 (binary16) - 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 位系统上可能是双精度) .我不知道任何提供半精度浮点的编译器。

总而言之,这是通常的:

大小(浮动)= 4

大小(双)= 8

sizeof(long double) = 8 或 16


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

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


char 并不总是 8 位,因此您的表达式在 architectures with non-8-bit char 上不起作用。只有 sizeof(type)*CHAR_BIT 个持有
即使 CHAR_BIT 被保证为 8 位,<< 3 也只是编写 * 8* CHAR_BIT 的一种混淆方式。
J
JCoder

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

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

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

和 MSDN 上的数据类型范围:

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

表达式 sizeof(type) * CHAR_BIT 计算为足以包含所需范围的位数,并且类型的排序仍然有效(例如 sizeof(int) <= sizeof(long))。实际特定于实现的范围可以在 C 或 C++ 中的 header 中找到(或者更好的是,在 header 中模板化 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();

这是正确的,但是,您说的也是正确的: char : 1 byte short : 2 bytes int : 4 bytes long : 4 bytes float : 4 bytes double : 8 bytes

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

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


我不确定这如何为 Alex's answer 添加任何内容,这是在此之前 6 年提供的?
P
Peter Mortensen

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

这是 Microsoft 编译器的编译器:Data Type Ranges


P
Peter Mortensen

您可以使用库提供的变量,例如 OpenGLQt 等。

例如Qtprovides qint8(在Qt支持的所有平台上保证为8位)、qint16、qint32、qint64、quint8、quint16、quint32、quint64等。


不回答问题
P
Peter Mortensen

在 64 位机器上:

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

在某些 64 位机器上,int 是 8 个字节,但不能保证另一个。没有什么说 char 应该只有 8 位。即使它是 64 位,也允许有 sizeof(void*)==4
P
Peter Mortensen

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

短整数:2字节

长整数:4 字节

long long 整数:8 字节

整数:取决于编译器(16 位、32 位或 64 位)


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