我正在寻找有关基本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
,{{的大小1}}(以及我没有想到的其他类型)在不同的架构和编译器下。
答案 0 :(得分:656)
C ++标准没有以字节为单位指定整数类型的大小,但它指定了它们必须能够容纳的最小范围。您可以从所需范围推断出最小位数。您可以从中推断出最小大小(以字节为单位)以及CHAR_BIT
宏defines the number of bits in a byte的值(除了最简陋的平台以外,它都是8,并且不能小于8)。
char
的另一个约束是它的大小总是1个字节,或CHAR_BIT
位(因此名称)。
最小范围required by the standard(第22页)是:
和MSDN上的数据类型范围:
signed char
:-127到127(请注意,不是-128到127;这适用于1-for-complement和sign-and-magnitude平台)unsigned char
:0到255 char
:与signed char
或unsigned char
相同的范围,implementation-defined signed short
: - 32767到32767 unsigned short
:0到65535 signed int
: - 32767到32767 unsigned int
:0到65535 signed long
: - 2147483647至2147483647 unsigned long
:0到4294967295 signed long long
: - 9223372036854775807至9223372036854775807 unsigned long long
:0至18446744073709551615 C ++(或C)实现可以将字节sizeof(type)
的大小定义为任意值,只要
sizeof(type) * CHAR_BIT
的计算结果为足以包含所需范围的位数,sizeof(int) <= sizeof(long)
)。实际的特定于实现的范围可以在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 - 即int
,long
和指针都是32位数量。
对于64位系统,主要的Unix'事实上'标准是LP64 - long
,指针是64位(但int
是32位)。 Windows 64位标准是LLP64 - long long
,指针是64位(但long
和int
都是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)
答案 5 :(得分:35)
更新:C ++ 11将TR1的类型正式纳入标准:
来自<cstdint>
另外,你得到:
这些类型表示至少具有指定位数的最小整数类型。同样,“最快”的整数类型至少具有指定的位数:
“快速”意味着什么,取决于实施。它也不一定是所有目的中最快的。
答案 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 = int
,long 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)
1)文章“The forgotten problems of 64-bit programs development”
中的表N12)“Data model”
答案 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;
其中X
是char
,int
,long
等..会以比特为单位给出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位系统也倾向于使用这些并具有扩展/修改。 请参阅此信息以获取更多信息:
答案 20 :(得分:0)
我注意到这里的所有其他答案几乎都专注于整数类型,而提问者也询问了浮点数。
我不认为C ++标准需要它,但是目前最常见平台的编译器通常遵循IEEE754标准的浮点数。该标准规定了四种类型的二进制浮点(以及一些BCD格式,我在C ++编译器中从未见过这种格式):
这如何映射到C ++类型呢?通常float
使用单精度;因此,sizeof(float) = 4
。然后double
使用双精度(我相信它是名称double
的来源),long double
可以是双精度或四倍精度(它是四倍的精度)我的系统,但在32位系统上它可能是双倍的)。我不知道任何提供半精度浮点数的编译器。
总之,这是通常的:
sizeof(float)
= 4 sizeof(double)
= 8 sizeof(long double)
= 8或16 答案 21 :(得分:-1)
例如,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)
根据大小有四种类型的整数: