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(以及其他我没有想到的类型)在不同的架构和编译器下的大小,但没有太多成功。

1313371 次浏览

如前所述,大小应该反映当前架构。如果您想查看当前编译器如何处理事情,您可以在limits.h中查看峰值。

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

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

有五种标准有符号整数类型:有符号char、短int、int、long int和long long int。在此列表中,每种类型提供的存储空间至少与列表中之前的类型相同。

对于每种标准有符号整数类型,都存在一个对应的(但不同的)标准无符号整数类型:无符号char、无符号短整数、无符号整数、无符号长整数和无符号长整数,每种类型占用相同的存储量并具有相同的对齐要求。

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

正如你提到的-它在很大程度上取决于编译器和平台。为此,请查看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;
}

可以在RogueWave中找到圣d::numeric_limits的文档。它包括大量其他命令,您可以调用这些命令来找出各种限制。这可以用于任何传递大小的任意类型,例如std::流式大小。

John的回答包含了最好的描述,因为这些描述保证能够成立。无论您在哪个平台上,还有另一个好的页面可以更详细地说明每个类型必须包含多少位:int类型,这是在标准中定义的。

我希望这有帮助!

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

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

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

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

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

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

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. “普通”char:与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 to 4294967295
  10. signed long long:92233720368547758079223372036854775807
  11. unsigned long long:018446744073709551615

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

  1. 表达式sizeof(type) * CHAR_BIT计算为足够高的位数以包含所需的范围,并且
  2. 类型的排序仍然有效(例如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();

对于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位的。

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

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

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

“快”意味着什么,如果有的话,取决于实现。对于所有目的,它也不一定是最快的。

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

例如,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)

第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:

有符号整数类型有五种: “有符号字符”,“短整型”,“整型”, “long int”和“long long int”。在 此列表中,每种类型至少提供 和之前的一样多的存储空间 在列表中。纯整数有 自然大小建议 执行的体系结构 环境(44);另一个签名 提供整数类型以满足 特殊需要

(44)即大到足以容纳 INT_MIN范围内的任何值 INT_MAX,如标题中定义的 <climits>.

结论是:这取决于你正在研究的架构。任何其他假设都是错误的。

您可以使用:

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

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

基于大小的整数有四种类型:

  • 短整数:2字节
  • 长整数:4字节
  • long long整数: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,短,长,长(有符号和无符号版本)的列表,并扫描列表,并通过使用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<=短<=int<=长<=长”(浮点数和双精度与IEEE浮点数标准几乎一致,而长双精度通常与双精度相同-但在更当前的实现中可能更大)。

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

如果你真的需要一个特定位数的对象(意思是一系列代表整数的位),大多数编译器都有一些指定的方法;但它通常是不可移植的,即使是在ame公司为不同平台制作的编译器之间也是如此。一些标准和实践(尤其是限制. h等)足够常见,以至于大多数编译器都支持确定特定值范围的最佳匹配类型,但不支持确定使用的位数。(也就是说,如果你知道你需要保存0到127之间的值,你可以确定你的编译器支持8位的“int8”类型,它将足够大以容纳所需的全部范围,但不是像“int7”类型那样的7位完全匹配。

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

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

"有五种标准有符号整数类型:有符号char、短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;

其中Xcharintlong等…将为您提供X的位大小。

在64位机器上:

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

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

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

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

和MSDN上的数据类型范围:

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

表达式sizeof(type)*CHAR_BIT计算的位数足以包含所需的范围,并且 类型的排序仍然有效(例如sizeof(int)<=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();

这是正确的,但是,你也说得对: 字符:1字节 短:2字节 int:4字节 长:4字节 浮点数:4字节 双:8字节

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

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

我不认为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