C++ 是什么意思? 标准规定了int、long的大小?

发布于 2024-07-14 09:01:17 字数 443 浏览 3 评论 0原文

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

我试图找到可靠的信息,说明 charshortint的大小,但没有取得多大成功>longdoublefloat(以及其他我没有想到的类型)在不同的架构和编译器下。

I'm looking for detailed information regarding the size of basic C++ types.
I know that it depends on the architecture (16 bits, 32 bits, 64 bits) and the compiler.

But are there any standards for C++?

I'm using Visual Studio 2008 on a 32-bit architecture. Here is what I get:

char  : 1 byte
short : 2 bytes
int   : 4 bytes
long  : 4 bytes
float : 4 bytes
double: 8 bytes

I tried to find, without much success, reliable information stating the sizes of char, short, int, long, double, float (and other types I didn't think of) under different architectures and compilers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(24

初懵 2024-07-21 09:01:17

C++ 标准没有指定整数类型的大小(以字节为单位),但它指定了以位为单位的最小宽度(请参阅[basic.types.fundamental] p1)。 您可以从中推断出最小大小(以字节为单位)以及 定义一个字节中的位数。 在除了最不起眼的平台之外的所有平台中,它都是 8,并且不能小于 8。

char 的另一个限制是它的大小始终为 1 个字节,即 CHAR_BIT位(因此得名)。 请参阅[expr.sizeof] p1

宽度在 [tab:basic.fundamental.width]
最小/最大范围是这样的结果:

类型宽度 ≥最小 ≤最大 ≥
signed char8-128127
unsigned char80255
char8(见下文)(见下文)
有符号短16-3276832767
无符号短16065535
有符号整数16-3276832767
无符号整型16065535
有符号长整型32-21474836482147483647
符号长整型3204294967295
有符号长整型64-922337203685477580892233720368547 75807
<代码>unsigned long long64018446744073709551615

char 的范围是 signed charunsigned char,具体取决于哪个char 的基础类型(请参阅 [basic.fundamental] p7)。

历史记录:在 C++20 之前,不保证有符号整数的补码,并且最小值大于 1。 例如,signed char 的最小值为 -127 或更低。 在 C++11 之前,宽度是通过 C 标准定义的。

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

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

不保证 floatdouble 的大小,但 double 提供的精度至少与 float 一样高。

实际的特定于实现的范围可以在 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();

The C++ standard does not specify the size of integral types in bytes, but it specifies a minimum width in bits (see [basic.types.fundamental] p1). You can infer minimum size in bytes from that and the value of the CHAR_BIT macro that defines the number of bits in a byte. In all but the most obscure platforms it's 8, and it can't be less than 8.

One additional constraint for char is that its size is always 1 byte, or CHAR_BIT bits (hence the name). See [expr.sizeof] p1.

The widths are specified in [tab:basic.fundamental.width].
Minimum/maximum ranges are a consequence of that:

TypeWidth ≥Minimum ≤Maximum ≥
signed char8-128127
unsigned char80255
char8(see below)(see below)
signed short16-3276832767
unsigned short16065535
signed int16-3276832767
unsigned int16065535
signed long32-21474836482147483647
unsigned long3204294967295
signed long long64-92233720368547758089223372036854775807
unsigned long long64018446744073709551615

The range of char is either that of signed char or unsigned char, depending on which is the underlying type of char (see [basic.fundamental] p7).

Historical note: Before C++20, two's complement wasn't guaranteed for signed integers, and the minimum was one greater. For example, the minimum of signed char was -127 or lower. Before C++11, the widths were defined through the C standard.

A C++ (or C) implementation can define the size of a type in bytes sizeof(type) to any value, as long as

  1. the expression sizeof(type) * CHAR_BIT evaluates to a number of bits high enough to contain required ranges, and
  2. the ordering of type is still valid (e.g. sizeof(int) <= sizeof(long)).

No guarantee is made about the size of float or double except that double provides at least as much precision as float.

The actual implementation-specific ranges can be found in <limits.h> header in C, or <climits> in C++ (or even better, templated std::numeric_limits in <limits> header).

For example, this is how you will find maximum range for 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();
月下客 2024-07-21 09:01:17

对于 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) 立法,但均得到 C 标准的允许。

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

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

For 32-bit systems, the 'de facto' standard is ILP32 — that is, int, long and pointer are all 32-bit quantities.

For 64-bit systems, the primary Unix 'de facto' standard is LP64 — long and pointer are 64-bit (but int is 32-bit). The Windows 64-bit standard is LLP64 — long long and pointer are 64-bit (but long and int are both 32-bit).

At one time, some Unix systems used an ILP64 organization.

None of these de facto standards is legislated by the C standard (ISO/IEC 9899:1999), but all are permitted by it.

And, by definition, sizeof(char) is 1, notwithstanding the test in the Perl configure script.

Note that there were machines (Crays) where CHAR_BIT was much larger than 8. That meant, IIRC, that sizeof(int) was also 1, because both char and int were 32-bit.

沉鱼一梦 2024-07-21 09:01:17

实际上不存在这样的事情。 通常,您可以期望 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,它们各自占用相同的存储量并具有相同的对齐要求。

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

In practice there's no such thing. Often you can expect std::size_t to represent the unsigned native integer size on current architecture. i.e. 16-bit, 32-bit or 64-bit but it isn't always the case as pointed out in the comments to this answer.

As far as all the other built-in types go, it really depends on the compiler. Here's two excerpts taken from the current working draft of the latest C++ standard:

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.

If you want to you can statically (compile-time) assert the sizeof these fundamental types. It will alert people to think about porting your code if the sizeof assumptions change.

心凉怎暖 2024-07-21 09:01:17

有标准。

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

如果您关心可移植性,或者希望类型名称反映大小,您可以查看标头 ,其中可以使用以下宏:

int8_t
int16_t
int32_t
int64_t

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

There is standard.

C90 standard requires that

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

C99 standard requires that

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

Here is the C99 specifications. Page 22 details sizes of different integral types.

Here is the int type sizes (bits) for Windows platforms:

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

If you are concerned with portability, or you want the name of the type reflects the size, you can look at the header <inttypes.h>, where the following macros are available:

int8_t
int16_t
int32_t
int64_t

int8_t is guaranteed to be 8 bits, and int16_t is guaranteed to be 16 bits, etc.

吹梦到西洲 2024-07-21 09:01:17

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

If you need fixed size types, use types like uint32_t (unsigned integer 32 bits) defined in stdint.h. They are specified in C99.

江南烟雨〆相思醉 2024-07-21 09:01:17

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

  • long long int
  • unsigned long long int

以及

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • 中的“sized”类型(以及 unsigned 对应项) )。

再加上你得到:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • 加上未签名的对应项。

这些类型表示至少具有指定位数的最小整数类型。 同样,还有至少具有指定位数的“最快”整数类型:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • 加上无符号版本。

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

Updated: C++11 brought the types from TR1 officially into the standard:

  • long long int
  • unsigned long long int

And the "sized" types from <cstdint>

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (and the unsigned counterparts).

Plus you get:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • Plus the unsigned counterparts.

These types represent the smallest integer types with at least the specified number of bits. Likewise there are the "fastest" integer types with at least the specified number of bits:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • Plus the unsigned versions.

What "fast" means, if anything, is up to the implementation. It need not be the fastest for all purposes either.

泛泛之交 2024-07-21 09:01:17

C++ 标准是这样说的:

3.9.1,§2:

有五种有符号整数类型:
“有符号字符”,“短整型”,“整型”,
“长整型”和“长长整型”。 在
这个列表中,每种类型至少提供
与之前的存储一样多的存储
在列表中。 普通整数有
建议的自然尺寸
执行架构
环境(44); 对方签了字
提供整数类型以满足
特殊需求。

(44) 也就是说,足够大以包含
INT_MIN 和 范围内的任何值
INT_MAX,如标头中定义

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

The C++ Standard says it like this:

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>
.

The conclusion: It depends on which architecture you're working on. Any other assumption is false.

酒浓于脸红 2024-07-21 09:01:17

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

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

如果您想要固定大小的变量,您能做的最好的事情就是使用如下宏:

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

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

Nope, there is no standard for type sizes. Standard only requires that:

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

The best thing you can do if you want variables of a fixed sizes is to use macros like this:

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

Then you can use WORD to define your variables. It's not that I like this but it's the most portable way.

南笙 2024-07-21 09:01:17

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

For floating point numbers there is a standard (IEEE754): floats are 32 bit and doubles are 64. This is a hardware standard, not a C++ standard, so compilers could theoretically define float and double to some other size, but in practice I've never seen an architecture that used anything different.

笔芯 2024-07-21 09:01:17

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

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

typedef int int32;

int32 i;
int32 j;
...

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

typedef long int int32;

int32 i;
int32 j;
...

We are allowed to define a synonym for the type so we can create our own "standard".

On a machine in which sizeof(int) == 4, we can define:

typedef int int32;

int32 i;
int32 j;
...

So when we transfer the code to a different machine where actually the size of long int is 4, we can just redefine the single occurrence of int.

typedef long int int32;

int32 i;
int32 j;
...
北斗星光 2024-07-21 09:01:17

有一个标准,并在各种标准文件(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< 找到/a>. 它包括大量其他命令,您可以调用它来找出各种限制。 这可以与任何传递大小的任意类型一起使用,例如 std::streamsize。

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

我希望这有帮助!

There is a standard and it is specified in the various standards documents (ISO, ANSI and whatnot).

Wikipedia has a great page explaining the various types and the max they may store:
Integer in Computer Science.

However even with a standard C++ compiler you can find out relatively easily using the following code snippet:

#include <iostream>
#include <limits>


int main() {
    // Change the template parameter to the various different types.
    std::cout << std::numeric_limits<int>::max() << std::endl;
}

Documentation for std::numeric_limits can be found at Roguewave. It includes a plethora of other commands you can call to find out the various limits. This can be used with any arbitrary type that conveys size, for example std::streamsize.

John's answer contains the best description, as those are guaranteed to hold. No matter what platform you are on, there is another good page that goes into more detail as to how many bits each type MUST contain: int types, which are defined in the standard.

I hope this helps!

我的奇迹 2024-07-21 09:01:17

当涉及不同架构和不同编译器的内置类型时,只需使用编译器在您的架构上运行以下代码即可查看其输出。 下面显示了我的 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

When it comes to built in types for different architectures and different compilers just run the following code on your architecture with your compiler to see what it outputs. Below shows my Ubuntu 13.04 (Raring Ringtail) 64 bit g++4.7.3 output. Also please note what was answered below which is why the output is ordered as such:

"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."

#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
青朷 2024-07-21 09:01:17

您可以使用:

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

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

You can use:

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

datatype = int, long int etc.
You will be able to see the size for whichever datatype you type.

情释 2024-07-21 09:01:17

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

As mentioned the size should reflect the current architecture. You could take a peak around in limits.h if you want to see how your current compiler is handling things.

深爱成瘾 2024-07-21 09:01:17

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

}

If you are interested in a pure C++ solution, I made use of templates and only C++ standard code to define types at compile time based on their bit size.
This make the solution portable across compilers.

The idea behind is very simple: Create a list containing types char, int, short, long, long long (signed and unsigned versions) and the scan the list and by the use of numeric_limits template select the type with given size.

Including this header you got 8 type stdtype::int8, stdtype::int16, stdtype::int32, stdtype::int64, stdtype::uint8, stdtype::uint16, stdtype::uint32, stdtype::uint64.

If some type cannot be represented it will be evaluated to stdtype::null_type also declared in that header.

THE CODE BELOW IS GIVEN WITHOUT WARRANTY, PLEASE DOUBLE CHECK IT.
I'M NEW AT METAPROGRAMMING TOO, FEEL FREE TO EDIT AND CORRECT THIS CODE.
Tested with DevC++ (so a gcc version around 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;

}
淡淡的优雅 2024-07-21 09:01:17

正如其他人所回答的那样,“标准”都将大部分细节保留为“实现定义”,并且仅声明类型“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 位。)

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

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

As others have answered, the "standards" all leave most of the details as "implementation defined" and only state that type "char" is at leat "char_bis" wide, and that "char <= short <= int <= long <= long long" (float and double are pretty much consistent with the IEEE floating point standards, and long double is typically same as double--but may be larger on more current implementations).

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.)

Note: Many Un*x source packages used "./configure" script which will probe the compiler/system's capabilities and output a suitable Makefile and config.h. You might examine some of these scripts to see how they work and how they probe the comiler/system capabilities, and follow their lead.

野の 2024-07-21 09:01:17

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

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

I notice that all the other answers here have focused almost exclusively on integral types, while the questioner also asked about floating-points.

I don't think the C++ standard requires it, but compilers for the most common platforms these days generally follow the IEEE754 standard for their floating-point numbers. This standard specifies four types of binary floating-point (as well as some BCD formats, which I've never seen support for in C++ compilers):

  • Half precision (binary16) - 11-bit significand, exponent range -14 to 15
  • Single precision (binary32) - 24-bit significand, exponent range -126 to 127
  • Double precision (binary64) - 53-bit significand, exponent range -1022 to 1023
  • Quadruple precision (binary128) - 113-bit significand, exponent range -16382 to 16383

How does this map onto C++ types, then? Generally the float uses single precision; thus, sizeof(float) = 4. Then double uses double precision (I believe that's the source of the name double), and long double may be either double or quadruple precision (it's quadruple on my system, but on 32-bit systems it may be double). I don't know of any compilers that offer half precision floating-points.

In summary, this is the usual:

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8 or 16
烦人精 2024-07-21 09:01:17

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

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

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

MSDN 上的数据类型范围:

signed char:-127 到 127(注意,不是 -128 到 127;这适用于 1 的补码平台)
无符号字符:0 到 255
“plain”字符:-127 到 127 或 0 到 255(取决于默认字符符号)
有符号短:-32767 到 32767
无符号短:0 到 65535
有符号整数:-32767 到 32767
无符号整数:0 到 65535
有符号长:-2147483647 到 2147483647
无符号长整型:0 到 4294967295
有符号长长:-9223372036854775807 到 9223372036854775807
无符号长整型: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字节
整数:4字节
长:4字节
浮点数:4字节
double : 8 字节

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

http://en.cppreference.com/w/cpp/语言/类型

From Alex B The C++ standard does not specify the size of integral types in bytes, but it specifies minimum ranges they must be able to hold. You can infer minimum size in bits from the required range. You can infer minimum size in bytes from that and the value of the CHAR_BIT macro that defines the number of bits in a byte (in all but the most obscure platforms it's 8, and it can't be less than 8).

One additional constraint for char is that its size is always 1 byte, or CHAR_BIT bits (hence the name).

Minimum ranges required by the standard (page 22) are:

and Data Type Ranges on 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

the expression sizeof(type) * CHAR_BIT evaluates to the number of bits enough to contain required ranges, and
the ordering of type is still valid (e.g. sizeof(int) <= sizeof(long)).
The actual implementation-specific ranges can be found in header in C, or in C++ (or even better, templated std::numeric_limits in header).

For example, this is how you will find maximum range for 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();

This is correct, however, you were also right in saying that:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double : 8 bytes

Because 32 bit architectures are still the default and most used, and they have kept these standard sizes since the pre-32 bit days when memory was less available, and for backwards compatibility and standardization it remained the same. Even 64 bit systems tend to use these and have extentions/modifications.
Please reference this for more information:

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

路弥 2024-07-21 09:01:17

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

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

As you mentioned - it largely depends upon the compiler and the platform. For this, check the ANSI standard, http://home.att.net/~jackklein/c/inttypes.html

Here is the one for the Microsoft compiler: Data Type Ranges.

ㄖ落Θ余辉 2024-07-21 09:01:17
unsigned char bits = sizeof(X) << 3;

其中 Xcharintlong 等。将为您提供 X< 的大小/code> 以位为单位。

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

where X is a char,int,long etc.. will give you size of X in bits.

清秋悲枫 2024-07-21 09:01:17

您可以使用 OpenGLQt 等。

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

You can use variables provided by libraries such as OpenGL, Qt, etc.

For example, Qt provides qint8 (guaranteed to be 8-bit on all platforms supported by Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.

千里故人稀 2024-07-21 09:01:17

在 64 位机器上:

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

On a 64-bit machine:

int: 4
long: 8
long long: 8
void*: 8
size_t: 8
久随 2024-07-21 09:01:17

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

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

There are four types of integers based on size:

  • short integer: 2 byte
  • long integer: 4 byte
  • long long integer: 8 byte
  • integer: depends upon the compiler (16 bit, 32 bit, or 64 bit)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文