C ++标准规定了int的大小,long类型是什么?

时间:2009-02-26 07:59:23

标签: c++ c++-faq

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

我试图在没有太大成功的情况下找到可靠的信息,说明charshortintlongdouble,{{的大小1}}(以及我没有想到的其他类型)在不同的架构和编译器下。

24 个答案:

答案 0 :(得分:656)

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

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

最小范围required by the standard(第22页)是:

MSDN上的数据类型范围:

  1. signed char:-127到127(请注意,不是-128到127;这适用于1-for-complement和sign-and-magnitude平台)
  2. unsigned char:0到255
  3. “plain”char:与signed charunsigned char相同的范围,implementation-defined
  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
  12. C ++(或C)实现可以将字节sizeof(type)的大小定义为任意值,只要

    1. 表达式sizeof(type) * CHAR_BIT的计算结果为足以包含所需范围的位数,
    2. 类型的排序仍然有效(例如sizeof(int) <= sizeof(long))。
    3. 实际的特定于实现的范围可以在C中的<limits.h>标头中找到,或者在C ++中的<climits>中找到(或者在std::numeric_limits标头中更好,模板<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();
      

答案 1 :(得分:228)

对于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配置脚本中进行了测试。

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

答案 2 :(得分:87)

在实践中没有这样的事情。通常,您可以期望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,每个都占用相同的存储量并具有相同的对齐要求。

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

答案 3 :(得分:79)

有标准。

C90标准要求

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

C99标准要求

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

Here is the C99 specifications。 Page 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位等。

答案 4 :(得分:38)

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

答案 5 :(得分:35)

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

  • long long int
  • 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
  • 加上未签名的版本。

“快速”意味着什么,取决于实施。它也不一定是所有目的中最快的。

答案 6 :(得分:18)

C++ Standard这样说:

3.9.1,§2:

  

有五种有符号整数类型:   “signed char”,“short int”,“int”,   “long int”和“long long int”。在   这个列表,每种类型至少提供   与之前一样多的存储空间   在列表中。平原有   建议的自然尺寸   执行的架构   环境(44);另一个签了   提供整数类型以满足   特殊需要。

     

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

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

答案 7 :(得分:12)

没有,类型大小没有标准。标准仅要求:

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

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

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

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

答案 8 :(得分:10)

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

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

typedef int int32;

int32 i;
int32 j;
...

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

typedef long int int32;

int32 i;
int32 j;
...

答案 9 :(得分:8)

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

答案 10 :(得分:7)

您可以使用:

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

datatype = intlong int等 无论您键入哪种数据类型,都可以看到大小。

答案 11 :(得分:7)

对于不同体系结构和不同编译器的内置类型,只需在您的体系结构上使用编译器运行以下代码,以查看它输出的内容。下面显示了我的Ubuntu 13.04(Raring Ringtail)64位g ++ 4.7.3输出。另请注意下面的答案,这就是为什么输出如此订购:

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

#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

答案 12 :(得分:7)

答案 13 :(得分:7)

有一个标准,它在各种标准文件(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。

John的回答包含最佳描述,因为这些描述可以保证。无论你在哪个平台上,都有另一个很好的页面可以更详细地说明每种类型必须包含多少位:int types,它们在标准中定义。

我希望这有帮助!

答案 14 :(得分:4)

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

答案 15 :(得分:2)

正如其他人已经回答的那样,“标准”都将大部分细节留作“实现定义”,并且只说“char”类型为“char_bis”宽,并且“char&lt; = short&lt; = int&lt; = long&lt; = 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。您可以查看其中一些脚本,了解它们的工作原理以及它们如何探测编译器/系统功能,并遵循它们的主导。

答案 16 :(得分:1)

如果您对纯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进行求值。

下面的代码没有保修,请仔细检查。
我是METAPROGRAMMING TOO的新手,可以免费编辑和更正此代码。
用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 :(得分:0)

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

以下是Microsoft编译器的一个: Data Type Ranges

答案 18 :(得分:0)

unsigned char bits = sizeof(X) << 3;

其中Xcharintlong等..会以比特为单位给出X的大小。

答案 19 :(得分:0)

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

char的另一个约束是它的大小总是1个字节,或者是CHAR_BIT位(因此是名称)。

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

MSDN上的

和数据类型范围:

签名字符:-127到127(注意,不是-128到127;这适用于1-for-complement平台) unsigned char:0到255 “plain”char:-127到127或0到255(取决于默认的char签名) 签署简报:-32767至32767 unsigned short:0到65535 signed int:-32767到32767 unsigned int:0到65535 签署长:-2147483647至2147483647 unsigned long:0到4294967295 签署长多头:-9223372036854775807至9223372036854775807 unsigned long long:0到18446744073709551615 C ++(或C)实现可以将字体sizeof(type)的类型大小定义为任何值,只要

表达式sizeof(type)* CHAR_BIT计算为足以包含所需范围的位数,以及 类型的排序仍然有效(例如sizeof(int)&lt; = sizeof(long))。 实际的特定于实现的范围可以在C中的头文件中找到,或者在C ++中找到(或者更好的是,标题中模板化的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个字节 短:2个字节 int:4个字节 long:4个字节 float:4个字节 double:8个字节

因为32位体系结构仍然是默认设置并且使用最多,并且它们保留了这些标准大小,因为在内存不太可用的前32位日期,并且为了向后兼容性和标准化,它保持不变。甚至64位系统也倾向于使用这些并具有扩展/修改。 请参阅此信息以获取更多信息:

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

答案 20 :(得分:0)

我注意到这里的所有其他答案几乎都专注于整数类型,而提问者也询问了浮点数。

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

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

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

总之,这是通常的:

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

答案 21 :(得分:-1)

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

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

答案 22 :(得分:-7)

在64位计算机上:

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

答案 23 :(得分:-8)

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

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