基础类型

来自cppreference.com
< cpp‎ | language

(类型系统概览见类型,以及参阅 C++ 库提供的类型相关的工具列表

void 类型

void - 值为空集的类型。它是无法变为完整的不完整类型(从而不允许存在 void 类型的对象)。不存在含有 void数组以及到 void引用。然而 指向 void 的指针和返回 void 类型的函数是允许存在的(其他语言中的过程)。

std::nullptr_t (C++11 起)

在标头 <cstddef> 定义
typedef decltype(nullptr) nullptr_t;
(C++11 起)

std::nullptr_t 是空指针字面量 nullptr 的类型。它是独立类型,既不是指针类型,也不是成员指针类型。

数据模型

每个实现关于基础类型大小所做的选择被统称为数据模型。有四个数据模型广为接受:

32 位系统:

  • LP322/4/4int 是 16 位,long 和指针是 32 位)
  • Win16 API
  • ILP324/4/4intlong 和指针是 32 位)
  • Win32 API
  • Unix 和类 Unix 系统(Linux、macOS)

64 位系统:

  • LLP644/4/8intlong 是 32 位,指针是 64 位)
  • LP644/8/8int 是 32 位,long 和指针是 64 位)
  • Unix 和类 Unix 系统(Linux、macOS)

其他数据模型很罕见。例如,ILP648/8/8intlong 和指针是 64 位)只会在某些早期 64 位 Unix 系统出现(例如 UNICOS on Cray)。

整数类型

标准整数类型

int - 基本整数类型。如果使用了下列任何修饰符就可以省略关键词 int。如果没有长度修饰符,那么它保证拥有至少 16 位宽度。然而在 32/64 位系统上,几乎专门保证它拥有至少 32 位宽度(见后述)。
修饰符

修饰整数类型。能以任何顺序混合使用。类型名中每组只能有一个。

  • 符号性
signed - 目标类型将拥有有符号表示(默认符号性)
unsigned - 目标类型将拥有无符号表示
  • 大小
short - 目标类型将为空间优化,且将有至少 16 位的宽度。
long - 目标类型将有至少 32 位的宽度。
long long - 目标类型将有至少 64 位的宽度。
(C++11 起)

注意:与所有类型说明符相同,容许采用任何顺序:unsigned long long intlong int unsigned long 指名同一类型。

性质

下表总结了所有可用的整数类型及它们在各种常用数据模型中的性质:

类型说明符 等价类型 按数据模型的位宽
C++ 标准 LP32 ILP32 LLP64 LP64
short
short int 至少 16 16 16 16 16
short int
signed short
signed short int
unsigned short
unsigned short int
unsigned short int
int
int 至少 16 16 32 32 32
signed
signed int
unsigned
unsigned int
unsigned int
long
long int 至少 32 32 32 32 64
long int
signed long
signed long int
unsigned long
unsigned long int
unsigned long int
long long
long long int
(C++11)
至少 64 64 64 64 64
long long int
signed long long
signed long long int
unsigned long long
unsigned long long int
(C++11)
unsigned long long int

注意:整数算术对有符号和无符号整数类型的定义是不同的。见算术运算符,特别是整数溢出

std::size_tsizeof 运算符还有 sizeof... 运算符及 alignof 运算符 (C++11 起)的结果的无符号整数类型。

扩展整数类型 (C++11 起)

扩展整数类型由实现定义。注意定宽整数类型典型情况下是标准整数类型的别名。

布尔类型

bool - 足以存放两个值 truefalse 之一的类型。sizeof(bool) 的值由实现定义,而且不一定是 1。

字符类型

signed char - 有符号字符表示的类型。
unsigned char - 无符号字符表示的类型。也会用来审查对象表示(无修饰内存)。
char - 能在目标系统上最有效地处理的字符表示的类型(拥有与 signed charunsigned char 之一相同的表示和对齐,但始终是独立的类型)。多字节字符串用此类型表示编码单元。对于每个范围 [0, 255] 中的 unsigned char 类型值,将该值转换成 char 再转换回 unsigned char 产生原值。 (C++11 起) char 的符号性取决于编译器和目标平台:ARM 和 PowerPC 的默认设置通常没有符号,而 x86 与 x64 的默认设置通常有符号。
wchar_t - 宽字符表示的类型(见宽字符串)。它与上述整数类型之一具有相同的大小、符号性和对齐,但它是独立的类型。实践中,它在 Linux 与许多其他非 Windows 系统上为 32 位并保有 UTF-32,但在 Windows 上为 16 位并保有 UTF-16 编码单元。标准曾要求 wchar_t 足够大以保有任何受支持的字符码位。然而该要求无法在 Windows 上满足,从而它被视为缺陷并被移除。
char16_t - UTF-16 字符表示的类型,要求大到足以表示任何 UTF-16 编码单元(16 位)。它与 std::uint_least16_t 具有相同的大小、符号性和对齐,但它是独立的类型。
char32_t - UTF-32 字符表示的类型,要求大到足以表示任何 UTF-32 编码单元(32 位)。它与 std::uint_least32_t 具有相同的大小、符号性和对齐,但它是独立的类型。
(C++11 起)
char8_t - UTF-8 字符表示的类型,要求大到足以表示任何 UTF-8 编码单元(8 位)。它与 unsigned char 具有相同的大小、符号性和对齐(从而与 charsigned char 具有相同的大小和对齐),但它是独立的类型。
(C++20 起)

除了最小位数,C++ 标准还保证

1 == sizeof(char)sizeof(short)sizeof(int)sizeof(long)sizeof(long long)

注意:这允许一种极端情况,其中字节有 64 位大小,所有类型(包括 char)都有 64 位宽,而 sizeof 对每个类型均返回 1。

浮点类型

标准浮点类型

下列三种类型和它们的 cv 限定版本统称为标准浮点类型。

float - 单精度浮点类型。如果支持就会匹配 IEEE-754 binary32 格式
double - 双精度浮点类型。如果支持就会匹配 IEEE-754 binary64 格式
long double - 扩展精度浮点类型。如果支持就会匹配 IEEE-754 binary128 格式,否则如果支持就会匹配 IEEE-754 binary64 扩展格式,否则匹配某种精度优于 binary64 而值域至少和 binary64 一样好的非 IEEE-754 扩展浮点格式,否则匹配 IEEE-754 binary64 格式。
  • 一些 HP-UX、SPARC、MIPS、ARM64 和 z/OS 实现使用 binary128 格式。
  • 最知名的 IEEE-754 binary64 扩展格式是 80 位 x87 扩展精度格式。许多 x86 和 x86-64 实现使用它(一个典型的例外是 MSVC,它将 long double 实现为与 double 相同的格式,即 binary 64)。

扩展浮点类型 (C++23 起)

扩展浮点类型由实现定义。可能会包含定宽浮点类型

性质

浮点类型可以支持一些特殊值

  • 无穷(正和负),见 INFINITY
  • 负零-0.0。它与正零比较相等,但在某些算术运算中有意义,例如 1.0 / 0.0 == INFINITY,但 1.0 / -0.0 == -INFINITY),而且对某些数学函数有意义,例如 sqrt(std::complex)
  • 非数(NaN),它与任何值(包括自身)比较都不相等。多个位模式都表示 NaN,见 std::nanNAN。注意 C++ 并会不对发信 NaN 进行特殊对待,它会把所有 NaN 都当做静默 NaN,但提供了 std::numeric_limits::has_signaling_NaN 用以检测它们的支持情况。

实浮点数可以用于算术运算符 + - / * 和各种来自 <cmath> 的数学函数。内建运算符和库函数都可能会引发浮点异常,并按 math errhandling 中的描述设置 errno

浮点表达式可以拥有大于它的类型所指定的值域和精度,见 FLT_EVAL_METHOD。浮点表达式也可以收缩,即在计算时将所有中间值视为拥有无限范围和精度,见 #pragma STDC FP_CONTRACT。标准 C++ 不限制浮点操作的准确度。

浮点数上的某些运算受浮点环境的状态影响,并可以对它进行修改(最值得注意的是舍入方向)。

在实浮点类型和整数类型间定义了隐式转换

浮点类型的其他细节、界限和性质见浮点类型的界限std::numeric_limits

取值范围

下表提供常用数值表示的界限的参考。

C++20 之前,C++ 标准曾允许任意的有符号整数表示,而 N 位有符号整数的最小保证范围从 -(2N-1
-1)
+2N-1
-1
(例如有符号 8 位类型是 -127127),这与反码原码的界限对应。

然而,所有 C++ 编译器均使用补码表示,而从 C++20 起,这是标准所允许的唯一表示,所保证的范围从 -2N-1
+2N-1
-1
(例如有符号 8 位类型是 -128127)。

C++11 起(经由 CWG 问题 1759的解决方案)char 不能再由 8 位反码与原码表示,因为用于 UTF-8 字符串字面量的值为 0x80 的 UTF-8 编码单元必须能在 char 类型对象中存储。

类型 位数 格式 取值范围
近似 精确
字符 8 有符号 -128127
无符号 0255
16 UTF-16 065535
32 UTF-32 01114111 (0x10ffff)
整数 16 有符号 ± 3.27 · 104 -3276832767
无符号 06.55 · 104 065535
32 有符号 ± 2.14 · 109 -2,147,483,6482,147,483,647
无符号 04.29 · 109 04,294,967,295
64 有符号 ± 9.22 · 1018 -9,223,372,036,854,775,8089,223,372,036,854,775,807
无符号 01.84 · 1019 018,446,744,073,709,551,615
二进制浮点 32 IEEE-754
  • 最小非正规:
    ± 1.401,298,4 · 10-45
  • 最小正规:
    ± 1.175,494,3 · 10-38
  • 最大:
    ± 3.402,823,4 · 1038
  • 最小非正规:
    ±0x1p-149
  • 最小正规:
    ±0x1p-126
  • 最大:
    ±0x1.fffffep+127
64 IEEE-754
  • 最小非正规:
    ± 4.940,656,458,412 · 10-324
  • 最小正规:
    ± 2.225,073,858,507,201,4 · 10-308
  • 最大:
    ± 1.797,693,134,862,315,7 · 10308
  • 最小非正规:
    ±0x1p-1074
  • 最小正规:
    ±0x1p-1022
  • 最大:
    ±0x1.fffffffffffffp+1023
80[注 1] x86
  • 最小非正规:
    ± 3.645,199,531,882,474,602,528
     · 10-4951
  • 最小正规:
    ± 3.362,103,143,112,093,506,263
     · 10-4932
  • 最大:
    ± 1.189,731,495,357,231,765,021
     · 104932
  • 最小非正规:
    ±0x1p-16446
  • 最小正规:
    ±0x1p-16382
  • 最大:
    ±0x1.fffffffffffffffep+16383
128 IEEE-754
  • 最小非正规:
    ± 6.475,175,119,438,025,110,924,
    438,958,227,646,552,5 · 10-4966
  • 最小正规:
    ± 3.362,103,143,112,093,506,262,
    677,817,321,752,602,6 · 10-4932
  • 最大:
    ± 1.189,731,495,357,231,765,085,
    759,326,628,007,016,2 · 104932
  • 最小非正规:
    ±0x1p-16494
  • 最小正规:
    ±0x1p-16382
  • 最大:
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
  1. 在 32/64 位平台上对象表示通常占用 96/128 位。

注意:这些类型能够表示的值的实际界限(与保证的最小界限相对)可以通过 C 数值界限接口std::numeric_limits 获知。

注解

功能特性测试 标准 注释
__cpp_unicode_characters 200704L (C++11) 新字符类型 (char16_tchar32_t)
__cpp_char8_t 201811L (C++20) char8_t
202207L (C++23) char8_t 兼容性和移植性修复 (允许从 UTF-8 string literals 聚合初始化 (unsigned) char 数组)

关键词

voidbooltruefalsecharwchar_tchar8_t (C++20 起) char16_tchar32_t (C++11 起) intshortlongsignedunsignedfloatdouble

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
CWG 238 C++98 未指明浮点实现会受哪些约束 指明不受约束
CWG 1759 C++11 不保证 char 能表示 UTF-8 代码单元 0x80 已保证
P2460R2 C++98 wchar_t 需要能够以不同代码表示所有支持的本地环境中最大的扩展字符集中的每个成员 不再需要

参阅