Namespaces
Variants

Arithmetic types

From cppreference.net

(另见 type 以获取类型系统概述,以及 C 库提供的类型相关工具列表 。)

目录

布尔类型

  • _Bool (也可通过宏 bool 访问) (C23前) bool (C23起) — 能够持有两个值之一的类型: 1 0 (也可通过宏 true false 访问) (C23前) true false (C23起)

注意 转换 _Bool (C23前) bool (C23起) 与其他整数类型的转换方式不同: ( bool ) 0.5 的计算结果为 true ,而 ( int ) 0.5 的计算结果为 0

(C99起)

字符类型

  • signed char — 用于有符号字符表示的类型。
  • unsigned char — 用于无符号字符表示的类型。亦用于检查 对象表示 (原始内存)。
  • char — 用于字符表示的类型。等价于 signed char unsigned char (具体取决于实现且可通过编译器命令行开关控制),但 char 是独立类型,与 signed char unsigned char 均不相同。

请注意,标准库还定义了 typedef 名称 wchar_t char16_t char32_t (自C11起) 用于表示宽字符 以及 char8_t 用于UTF-8字符 (自C23起)

整数类型

  • short int (也可写作 short ,可使用关键字 signed
  • unsigned short int (也可写作 unsigned short
  • int (也可写作 signed int
这是平台最优的整数类型,保证至少为16位。当前大多数系统使用32位(参见下文数据模型)。
  • unsigned int (也可写作 unsigned ),是 int 的无符号对应类型,实现模运算。适用于位操作。
  • long int (也可写作 long
  • unsigned long int (也可写作 unsigned long
  • long long int (也可写作 long long
  • unsigned long long int (也可写作 unsigned long long
(C99起)
  • _BitInt ( n ) (也可写作 signed _BitInt ( n ) ),精确位宽有符号整数类型(其中 n 需替换为表示精确位宽(包含符号位)的整数常量表达式,其值不得超过 BITINT_MAXWIDTH (定义于 <limits.h> ))
  • unsigned _BitInt ( n ) ,精确位宽无符号整数类型(其中 n 需替换为表示精确位宽的整数常量表达式,其值不得超过 BITINT_MAXWIDTH (定义于 <limits.h> ))
(C23起)

注意:与所有类型说明符一样,允许任意顺序: unsigned long long int long int unsigned long 表示同一类型。

以下表格总结了所有可用的整数类型及其属性:

(注:根据要求,所有HTML标签、属性及 标签内的C++专业术语"signed char"均保持原文未翻译) (说明:由于要求不翻译 标签内的C++术语,且原文中所有内容均位于代码标签内,因此完整保留了原始内容) (说明:根据要求,HTML标签和属性保持不变, 标签内的C++关键字"signed"、"short"、"int"属于C++术语不予翻译,因此整段内容保持原样输出) (说明:根据要求,所有HTML标签、属性及 标签内的C++专业术语均保持原样未翻译,仅对非代码部分进行了简体中文翻译。由于原文中所有文本内容均位于 标签内且为C++术语,故最终输出与原文完全一致) (注:根据要求,所有HTML标签和属性均未翻译, 标签内的C++关键字"signed long long"作为专业术语保留原文) (说明:根据要求,HTML标签和属性保持不变, 标签内的C++关键字"signed long long int"属于C++术语不予翻译,因此整段内容保持原样输出)
类型说明符 等效类型 不同数据模型下的位宽
C 标准 LP32 ILP32 LLP64 LP64
char
char 至少
8
8 8 8 8
signed char
signed char
unsigned char
unsigned char
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
(C99)
至少
64
64 64 64 64
long long int
signed long long
signed long long int
unsigned long long
unsigned long long int
(C99)
unsigned long long int

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

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

注意:这种情况允许极端场景,即 byte 可被定义为64位,所有类型(包括 char )均为64位宽,且 sizeof 对所有类型都返回 1

注意:有符号和无符号整数类型的整数运算定义不同。请参阅 算术运算符 ,特别是 整数溢出 部分。

数据模型

每个实现对于基本类型大小所做的选择统称为 数据模型 。目前有四种数据模型获得广泛认可:

32 位系统:

  • LP32 2/4/4 ( int 为16位, long 和指针为32位)
  • Win16 API
  • ILP32 4/4/4 ( int long 和指针均为32位);
  • Win32 API
  • Unix及类Unix系统(Linux, Mac OS X)

64 位系统:

  • LLP64 4/4/8 ( int long 为32位,指针为64位)
  • Win64 API
  • LP64 4/8/8 ( int 为32位, long 和指针为64位)
  • Unix及类Unix系统 (Linux, Mac OS X)

其他模型非常罕见。例如, ILP64 ( 8/8/8 : int long 及指针均为64位)仅出现在某些早期64位Unix系统中(例如 Cray平台上的Unicos )。

注意精确宽度整数类型自 C99 起已在 <stdint.h> 中提供。

实数浮点类型

C 语言有三种 或六种 (自 C23 起) 用于表示实浮点值的类型:

  • float — 单精度浮点类型。若支持则匹配 IEEE-754 binary32 格式
  • double — 双精度浮点类型。若支持则匹配 IEEE-754 binary64 格式
  • long double — 扩展精度浮点类型。若支持则匹配 IEEE-754 binary128 格式 ;否则若支持则匹配 IEEE-754 binary64 -扩展格式 ;否则匹配某些非IEEE-754扩展浮点格式(要求其精度优于 binary64 且范围至少与 binary64 相当);否则匹配IEEE-754 binary64 格式。
    • binary128 格式被部分HP-UX、SPARC、MIPS、ARM64和z/OS实现所采用。
    • 最著名的IEEE-754 binary64 -扩展格式是80位x87扩展精度格式。该格式被许多x86和x86-64实现采用(显著例外是MSVC,它将 long double 实现为与 double 相同的格式,即 binary64 )。
若实现预定义了宏常量 __STDC_IEC_60559_DFP__ ,则同时支持以下十进制浮点类型:
否则,不支持这些十进制浮点类型。
(自 C23 起)

浮点类型可能支持特殊值:

  • 无穷大 (正与负),参见 INFINITY
  • 负零 - 0.0 。其与正零比较相等,但在某些算术运算中具有意义,例如 1.0 / 0.0 == INFINITY ,但 1.0 / - 0.0 == - INFINITY
  • 非数值 (NaN),不与任何值(包括其自身)比较相等。存在多种位模式表示NaN,参见 nan NAN 。注意C语言不会特别处理信号NaN(由IEEE-754定义),并将所有NaN视为静默NaN。

实浮点数可与 算术运算符 + - / * 以及来自 <math.h> 的各种数学函数一起使用。内置运算符和库函数均可能触发浮点异常并设置 errno ,具体说明参见 math_errhandling

浮点表达式的取值范围和精度可能超过其类型所指示的范围,参见 FLT_EVAL_METHOD 赋值 return cast 操作会将取值范围和精度限制为声明类型对应的范围。

浮点表达式也可以被 收缩 ,即计算时如同所有中间值都具有无限范围和精度,参见 #pragma STDC FP_CONTRACT

对浮点数的某些操作会受 浮点环境 状态影响并修改其状态 (最显著的是舍入方向)。

隐式转换 在实浮点类型与整数类型、复数类型及虚数类型之间定义。

请参阅 浮点类型限制 以及 <math.h> 库以获取有关浮点类型的更多详细信息、限制和属性。

复数浮点类型

复数浮点类型模拟数学中的 复数 ,即可以表示为实数与实数乘以虚数单位之和的数字: a + bi

三种复杂类型是

注意:与所有类型说明符一样,允许任意顺序: long double complex complex long double 甚至 double complex long 都表示同一类型。

#include <complex.h>
#include <stdio.h>
int main(void)
{
    double complex z = 1 + 2*I;
    z = 1 / z;
    printf("1/(1.0+2.0i) = %.1f%+.1fi\n", creal(z), cimag(z));
}

输出:

1/(1.0+2.0i) = 0.2-0.4i

如果实现定义了宏常量 __STDC_NO_COMPLEX__ ,则不提供复数类型(以及库头文件 <complex.h> )。

(自 C11 起)

每种复数类型具有与对应实数类型的双元素 数组 相同的 对象表示 对齐要求 float 对应 float complex double 对应 double complex long double 对应 long double complex )。数组的第一个元素存储实部,第二个元素存储虚部。

float a[4] = {1, 2, 3, 4};
float complex z1, z2;
memcpy(&z1, a, sizeof z1); // z1 变为 1.0 + 2.0i
memcpy(&z2, a+2, sizeof z2); // z2 变为 3.0 + 4.0i

复数可与 算术运算符 + - * / 配合使用,并可与虚数和实数混合运算。 <complex.h> 中为复数定义了众多数学函数。内置运算符和库函数均可能触发浮点异常并设置 errno ,具体说明参见 math_errhandling

递增和递减操作未针对复数类型定义。

关系运算符未为复数类型定义(不存在“小于”的概念)。

隐式转换 are defined between complex types and other arithmetic types.

为了支持复数运算的一无穷大模型,C语言将任何至少包含一个无穷大部分的复数值视为无穷大,即使其另一部分为NaN,并保证所有运算符和函数遵循无穷大的基本性质,同时提供 cproj 函数将所有无穷大映射至规范形式(具体规则参见 算术运算符 章节)。

#include <complex.h>
#include <math.h>
#include <stdio.h>
int main(void)
{
    double complex z = (1 + 0*I) * (INFINITY + I*INFINITY);
//  教科书公式会得出
//  (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN
//  但C语言会给出复无穷大
    printf("%f%+f*i\n", creal(z), cimag(z));
//  教科书公式会得出
//  cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN
//  但C语言会给出 ±∞+i*nan
    double complex y = cexp(INFINITY + I*NAN);
    printf("%f%+f*i\n", creal(y), cimag(y));
}

可能输出:

inf+inf*i 
inf+nan*i

C语言同样处理多个无穷大值,以便在笛卡尔表示法的固有局限范围内尽可能保留方向信息:

将虚数单位乘以实无穷会得到正确符号的虚无穷:i × ∞ = i∞。同时,i × (∞ – i∞) = ∞ + i∞ 表明了合理的象限。

虚数浮点类型

虚浮点类型模拟数学中的 虚数 ,即可以表示为实数乘以虚数单位的数字: bi 。三种虚数类型包括

注意:与所有类型说明符一样,允许任意顺序: long double imaginary imaginary long double ,甚至 double imaginary long 都表示同一类型。

#include <complex.h>
#include <stdio.h>
int main(void)
{
    double imaginary z = 3*I;
    z = 1 / z;
    printf("1/(3.0i) = %+.1fi\n", cimag(z));
}

输出:

1/(3.0i) = -0.3i

推荐(但不要求)定义 __STDC_IEC_559_COMPLEX__ 的实现支持虚数。POSIX建议通过检查宏 _Imaginary_I 是否被定义来识别虚数支持。

(C11前)

若定义了 __STDC_IEC_559_COMPLEX__ (C23前) __STDC_IEC_60559_COMPLEX__ (C23起) 则支持虚数。

(C11起)

三种虚数类型各自具有与其 对应实数类型 相同的 对象表示 对齐要求 float 对应 float imaginary double 对应 double imaginary long double 对应 long double imaginary )。

注意:尽管如此,虚数类型是独立的,并且 不兼容 于它们对应的实数类型,这禁止了别名使用。

虚数可与 算术运算符 + - * / 结合使用,并可混合复数与实数运算。 <complex.h> 头文件中为虚数定义了多种数学函数。内置运算符和库函数均可能触发浮点异常,并按照 math_errhandling 所述设置 errno

递增和递减操作未为虚数类型定义。

隐式转换 are defined between imaginary types and other arithmetic types.

虚数类型使得能够使用自然记法 x + I * y 来表达所有复数(其中 I 被定义为 _Imaginary_I )。若没有虚数类型,某些特殊复数值将无法通过自然方式创建。例如,若将 I 定义为 _Complex_I ,则书写 0.0 + I * INFINITY 会导致实部为NaN,此时必须改用 CMPLX ( 0.0 , INFINITY ) 。对于具有负零虚部的数值也是如此,这些数值在使用具有分支切割的库函数(例如 csqrt )时具有特殊意义: 1.0 - 0.0 * I I 被定义为 _Complex_I 时会产生正零虚部,而负零虚部必须使用 CMPLX conj 来构造。

虚数类型还能简化实现;如果支持虚数类型,虚数与复数的乘法可以通过两次乘法直接实现,而不需要四次乘法和两次加法。

(自 C99 起)

关键词

说明:根据要求,所有HTML标签、属性及 标签内的C++关键字均未翻译,保持了原始格式和专业术语的准确性。

取值范围

下表提供了常见数值表示范围的参考。

在C23之前,C标准允许使用任何有符号整数表示形式,且N位有符号整数的最小保证范围是从 -(2 N-1
-1)
+2 N-1
-1
(例如8位有符号类型的范围为 -127 127 ),该范围对应 反码 原码 表示法的极限值。

然而,所有主流数据模型(包括ILP32、LP32、LP64、LLP64)及几乎所有C编译器均采用 二进制补码 表示法(目前已知的唯一例外是部分UNISYS系统编译器)。自C23标准起,这成为标准唯一允许的表示方式,其保证的取值范围为 -2 N-1
+2 N-1
-1
(例如8位有符号类型的取值范围为 -128 127 )。

类型 位宽 格式 取值范围
近似值 精确值
字符型 8 signed −128 127
unsigned 0 255
16 UTF-16 0 65535
32 UTF-32 0 1114111 ( 0x10ffff )
整型 16 signed ± 3.27 · 10 4 −32768 32767
unsigned 0 6.55 · 10 4 0 65535
32 signed ± 2.14 · 10 9 −2,147,483,648 2,147,483,647
unsigned 0 4.29 · 10 9 0 4,294,967,295
64 signed ± 9.22 · 10 18 −9,223,372,036,854,775,808 9,223,372,036,854,775,807
unsigned 0 1.84 · 10 19 0 18,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 · 10 38
  • 最小次正规数:
    ±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 · 10 308
  • 最小次正规数:
    ±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
    · 10 4932
  • 最小次正规数:
    ±0x1p−16445
  • 最小正规数:
    ±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 · 10 4932
  • 最小次正规数:
    ±0x1p−16494
  • 最小正规数:
    ±0x1p−16382
  • 最大值:
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
十进制
浮点型
32 IEEE-754
  • 最小次正规数:
    ± 1 · 10 -101
  • 最小正规数:
    ± 1 · 10 -95
  • 最大值:
    ± 9.999'999 · 10 96
64 IEEE-754
  • 最小次正规数:
    ± 1 · 10 -398
  • 最小正规数:
    ± 1 · 10 -383
  • 最大值:
    ± 9.999'999'999'999'999 · 10 384
128 IEEE-754
  • 最小次正规数:
    ± 1 · 10 -6176
  • 最小正规数:
    ± 1 · 10 -6143
  • 最大值:
    ± 9.999'999'999'999'999'999'
    999'999'999'999'999 · 10 6144
  1. 对象表示通常在32/64位平台上分别占用96/128位。

注意:实际(与保证的最小值相对)范围可在库头文件 <limits.h> <float.h> 中获取。

另请参阅

C++ 文档 关于 基础类型