我正在寻找关于基本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(以及其他我没有想到的类型)的大小的可靠信息,但没有多大成功。


如前所述,大小应该反映当前的体系结构。如果你想知道当前编译器是如何处理的,你可以在limits.h中取一个峰值。


实际上没有这样的事情。通常,std::size_t表示当前体系结构上的无符号本机整数大小。即16位、32位或64位,但并不总是如此,就像这个答案的评论中指出的那样。

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

There are five standard signed integer types : signed char, short int, int, long int, and long long int. In this list, each type provides at least as much storage as those preceding it in the list. For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: unsigned char, unsigned short int, unsigned int, unsigned long int, and unsigned long long int, each of which occupies the same amount of storage and has the same alignment requirements.

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


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

下面是微软编译器的一个:数据类型范围。


有一个标准,它是在各种标准文档(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;
}

std::numeric_limits的文档可以在Roguewave上找到。它包含大量其他命令,您可以调用这些命令来查找各种限制。这可以用于任何传递大小的任意类型,例如std::streamsize。

约翰的回答包含了最好的描述,因为那些肯定是成立的。不管你在什么平台上,有另一个很好的页面详细介绍了每种类型必须包含多少位:int类型,这是在标准中定义的。

我希望这能有所帮助!


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

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

如果你想要一个固定大小的变量,你能做的最好的事情就是像这样使用宏:

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

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


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


c++标准没有以字节为单位指定整型的大小,但它指定了它们必须能够容纳的最小范围。您可以从所需的范围推断出最小大小(以位为单位)。您可以从该值和CHAR_BIT宏的值推断出以字节为单位的最小大小,CHAR_BIT宏定义了字节中的比特数。除了最不知名的平台,其他平台都是8,而且不能小于8。

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

C标准是c++标准的规范参考,所以即使它没有明确地说明这些要求,c++也要求C标准所要求的最小范围(第22页),这与MSDN上的数据类型范围相同:

signed char: -127 to 127 (note, not -128 to 127; this accommodates 1's-complement and sign-and-magnitude platforms) unsigned char: 0 to 255 "plain" char: same range as signed char or unsigned char, implementation-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 long long: 0 to 18446744073709551615

c++(或C)实现可以用bytes sizeof(type)定义类型的大小为任何值,只要

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

综上所述,我们可以保证:

Char,有符号Char和无符号Char至少是8位 有符号short、无符号short、有符号int和无符号int至少是16位 有符号长和无符号长至少是32位 有符号long long和无符号long long至少是64位

对于float或double类型的大小没有任何保证,除非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();

对于32位系统,“事实上”的标准是ILP32——也就是说,int、long和pointer都是32位的量。

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

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

这些事实上的标准没有一个是由C标准(ISO/IEC 9899:1999)立法的,但都是被C标准所允许的。

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

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


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


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

Long Long int Unsigned long long int

以及<cstdint>中的"size "类型

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 加上无符号的版本。

“快”意味着什么,如果有的话,取决于实现。它也不需要在所有方面都是最快的。


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

2)“数据模型”


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

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


有标准。

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

如果你关心可移植性,或者你想要类型的名称反映大小,你可以查看头文件<inttypes.h>,其中有以下宏:

int8_t
int16_t
int32_t
int64_t

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


c++标准是这样说的:

3.9.1,§2:

There are five signed integer types : "signed char", "short int", "int", "long int", and "long long int". In this list, each type provides at least as much storage as those preceding it in the list. Plain ints have the natural size suggested by the architecture of the execution environment (44); the other signed integer types are provided to meet special needs. (44) that is, large enough to contain any value in the range of INT_MIN and INT_MAX, as defined in the header <climits>.

结论:这取决于您使用的是哪种体系结构。其他任何假设都是错误的。


你可以使用:

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

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


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

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


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

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

typedef int int32;

int32 i;
int32 j;
...

所以当我们把代码转移到另一台机器上,当long int的大小是4时,我们可以重新定义int的一次出现。

typedef long int int32;

int32 i;
int32 j;
...

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

}

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

Part of the reasons for not having very specific and exact values is because languages like C/C++ were designed to be portable to a large number of hardware platforms--Including computer systems in which the "char" word-size may be 4-bits or 7-bits, or even some value other than the "8-/16-/32-/64-bit" computers the average home computer user is exposed to. (Word-size here meaning how many bits wide the system normally operates on--Again, it's not always 8-bits as home computer users may expect.)

If you really need a object (in the sense of a series of bits representing an integral value) of a specific number of bits, most compilers have some method of specifying that; But it's generally not portable, even between compilers made by the ame company but for different platforms. Some standards and practices (especially limits.h and the like) are common enough that most compilers will have support for determining at the best-fit type for a specific range of values, but not the number of bits used. (That is, if you know you need to hold values between 0 and 127, you can determine that your compiler supports an "int8" type of 8-bits which will be large enought to hold the full range desired, but not something like an "int7" type which would be an exact match for 7-bits.)

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


当涉及到不同架构和不同编译器的内置类型时,只需在你的架构上用编译器运行以下代码,看看它输出了什么。下面是我的Ubuntu 13.04 (Raring Ringtail) 64位g++4.7.3输出。还请注意下面的回答,这就是为什么输出是这样排序的:

有五种标准的有符号整型:有符号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

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

其中X是char,int,long等。会得到X的比特大小。


在64位机器上:

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

c++标准没有以字节为单位指定整型的大小,但它指定了它们必须能够容纳的最小范围。您可以从所需的范围推断出最小大小(以位为单位)。您可以从该值和CHAR_BIT宏的值推断出最小的字节大小,CHAR_BIT宏定义了字节中的位数(除了最晦涩的平台之外,在所有平台中它都是8,而且不能小于8)。

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

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

MSDN上的数据类型范围:

signed char: -127 to 127 (note, not -128 to 127; this accommodates 1's-complement platforms) unsigned char: 0 to 255 "plain" char: -127 to 127 or 0 to 255 (depends on default char signedness) 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 long long: 0 to 18446744073709551615 A C++ (or C) implementation can define the size of a type in bytes sizeof(type) to any value, as long as

表达式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字节 短:2字节 Int: 4字节 Long: 4字节 浮点数:4字节 Double: 8字节

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

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


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

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

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

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

总结一下,通常是这样的:

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