727

我正在寻找有关基本 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

我试图在不同的架构和编译器下找到可靠的信息,说明char, short, int, long, double, float(以及我没有想到的其他类型)的大小。

4

24 回答 24

715

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

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

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

  1. signed char:-127 到 127(注意,不是 -128 到 127;这适用于 1 的补码和符号和幅度平台)
  2. unsigned char: 0 到 255
  3. “plain” :与orchar相同的范围,实现定义signed charunsigned char
  4. signed short: -32767 至 32767
  5. unsigned short: 0 到 65535
  6. signed int: -32767 至 32767
  7. unsigned int: 0 到 65535
  8. signed long:-2147483647 至 2147483647
  9. unsigned long: 0 到 4294967295
  10. signed long long: -9223372036854775807 至 9223372036854775807
  11. unsigned long long: 0 到 18446744073709551615

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

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

综上所述,我们保证:

  • char, signed char, 和unsigned char至少为 8 位
  • signed short, unsigned short, signed int, 和unsigned int至少为 16 位
  • signed long并且unsigned long至少为 32 位
  • signed long long并且unsigned long long至少为 64 位

不保证float或的大小至少提供与.doubledoublefloat

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

例如,您将通过以下方式找到 的最大范围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();
于 2009-02-26T08:47:43.623 回答
268

对于 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 大得多。这意味着 IIRCsizeof(int)也是 1,因为两者char都是int32 位的。

于 2009-02-26T08:47:59.490 回答
90

在实践中没有这样的事情。通常,您可以期望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 假设发生变化,它将提醒人们考虑移植您的代码。

于 2009-02-26T08:02:56.633 回答
84

有标准。

C90 标准要求

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

C99 标准要求

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

这是C99的规格。第 22 页详细介绍了不同整数类型的大小。

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

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

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

int8_t
int16_t
int32_t
int64_t

int8_t保证为8位,int16_t保证为16位等。

于 2009-03-30T14:49:54.030 回答
39

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

于 2009-02-26T08:18:12.260 回答
36

更新: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
  • 加上未签名的版本。

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

于 2009-02-26T19:32:40.530 回答
18

C++ 标准是这样说的:

3.9.1,§2:

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

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

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

于 2010-09-01T13:41:13.873 回答
12

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

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

如果您想要固定大小的变量,您可以做的最好的事情是使用这样的宏:

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

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

于 2009-02-26T08:07:09.040 回答
10

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

于 2009-02-26T08:49:36.147 回答
10

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

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

typedef int int32;

int32 i;
int32 j;
...

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

typedef long int int32;

int32 i;
int32 j;
...
于 2012-07-14T16:01:46.560 回答
7

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

维基百科有一个很棒的页面,解释了各种类型和它们可以存储的最大值: 计算机科学中的整数。

然而,即使使用标准 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;
}

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

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

我希望这有帮助!

于 2009-02-26T08:06:35.843 回答
6

当涉及到不同架构和不同编译器的内置类型时,只需使用编译器在您的架构上运行以下代码以查看它的输出。下面显示了我的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
于 2013-08-08T23:47:45.473 回答
5

您可以使用:

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

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

于 2011-06-14T06:19:18.543 回答
5

1)文章“ 64位程序开发中被遗忘的问题”中的表N1

2)“数据模型

于 2009-02-26T20:31:18.487 回答
3

如前所述,大小应反映当前架构。limits.h如果你想看看你当前的编译器是如何处理事情的,你可以去看看。

于 2009-02-26T08:01:31.893 回答
2

正如其他人所回答的那样,“标准”都将大部分细节保留为“实现定义”,并且仅声明“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。您可能会检查其中一些脚本以了解它们如何工作以及它们如何探测编译器/系统功能,并遵循它们的引导。

于 2013-05-27T07:04:36.367 回答
2

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

}
于 2012-10-26T17:43:10.087 回答
1

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

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

总而言之,这是通常的:

  • sizeof(float)= 4
  • sizeof(double)= 8
  • sizeof(long double)= 8 或 16
于 2015-07-01T13:56:32.647 回答
-1

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

这是 Microsoft 编译器的一个:数据类型范围

于 2009-02-26T08:06:08.467 回答
-1

来自 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

于 2015-02-23T19:05:49.933 回答
-1
unsigned char bits = sizeof(X) << 3;

Xa char,int等在哪里long。将为您提供X以位为单位的大小。

于 2014-01-02T18:25:25.897 回答
-3

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

比如Qt提供了qint8(保证Qt支持的所有平台都是8位的)、qint16、qint32、qint64、quint8、quint16、quint32、quint64等。

于 2009-03-09T10:22:30.310 回答
-10

在 64 位机器上:

int: 4
long: 8
long long: 8
void*: 8
size_t: 8
于 2015-02-07T23:27:31.683 回答
-12

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

  • 短整数:2字节
  • 长整数:4 字节
  • long long 整数:8 字节
  • 整数:取决于编译器(16 位、32 位或 64 位)
于 2011-09-15T23:18:37.010 回答