命名空间
变体
操作

算术类型

来自 cppreference.cn
< c‎ | language

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

目录

布尔类型

  • _Bool (也可作为宏 bool 访问)(C23 前)bool(C23 起) — 类型,能够容纳两个值之一:10 (也可作为宏 truefalse 访问)(C23 前)truefalse(C23 起)

请注意,转换为 _Bool(C23 前)bool(C23 起)转换 与转换为其他整数类型的工作方式不同:(bool)0.5 求值为 true,而 (int)0.5 求值为 0

(自 C99 起)

[编辑] 字符类型

  • signed char — 用于有符号字符表示的类型。
  • unsigned char — 用于无符号字符表示的类型。也用于检查对象表示(原始内存)。
  • char — 用于字符表示的类型。等同于 signed charunsigned char 之一(具体哪个由实现定义,并且可以通过编译器命令行开关控制),但 char 是一个独特的类型,与 signed charunsigned char 都不同。

请注意,标准库还定义了 typedef 名称 wchar_tchar16_tchar32_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 intlong int unsigned long 指的是相同的类型。

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

类型说明符 等效类型 按数据模型的位宽
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)

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

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

[编辑] 数据模型

每个实现关于基本类型大小的选择统称为数据模型。 四种数据模型被广泛接受

32 位系统

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

64 位系统

  • LLP644/4/8 ( intlong 是 32 位,指针是 64 位)
  • Win64 API
  • LP644/8/8 ( int 是 32 位,long 和指针是 64 位)
  • Unix 和类 Unix 系统 (Linux, Mac OS X)

其他模型非常罕见。 例如,ILP64 (8/8/8: intlong 和指针是 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-extended 格式,否则匹配一些非 IEEE-754 扩展浮点格式,只要其精度优于 binary64 并且范围至少与 binary64 一样好,否则匹配 IEEE-754 binary64 格式。
    • binary128 格式被一些 HP-UX、SPARC、MIPS、ARM64 和 z/OS 实现使用。
    • 最著名的 IEEE-754 binary64-extended 格式是 80 位 x87 扩展精度格式。 它被许多 x86 和 x86-64 实现使用(一个值得注意的例外是 MSVC,它以与 double 相同的格式实现 long 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赋值返回强制转换 将范围和精度强制为与声明类型关联的范围和精度。

浮点表达式也可能是收缩的,也就是说,计算时就好像所有中间值都具有无限的范围和精度,请参阅 #pragma STDC FP_CONTRACT

对浮点数的一些操作受到浮点环境状态的影响和修改(最值得注意的是,舍入方向)。

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

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

复浮点类型

复浮点类型模拟数学复数,即可写成实数与虚数单位乘积之和的数:a + bi

三种复数类型是

注意:与所有类型说明符一样,允许任何顺序:long double complexcomplex 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 complexdouble 用于 double complexlong double 用于 long double complex)。 数组的第一个元素保存实部,数组的第二个元素保存虚部。

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

复数可以与算术运算符 + - */ 一起使用,可以与虚数和实数混合使用。 <complex.h> 中为复数定义了许多数学函数。 内置运算符和库函数都可能引发浮点异常并设置 errno,如 math_errhandling 中所述。

未为复数类型定义递增和递减。

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

在复数类型和其他算术类型之间定义了隐式转换

为了支持复数算术的单无穷模型,C 将任何至少具有一个无穷部分的复数值都视为无穷大,即使其另一部分是 NaN,并保证所有运算符和函数都遵守无穷大的基本属性,并提供 cproj 以将所有无穷大映射到规范的无穷大(有关确切规则,请参阅算术运算符)。

#include <complex.h>
#include <math.h>
#include <stdio.h>
 
int main(void)
{
    double complex z = (1 + 0*I) * (INFINITY + I*INFINITY);
//  textbook formula would give
//  (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN
//  but C gives a complex infinity
    printf("%f%+f*i\n", creal(z), cimag(z));
 
//  textbook formula would give
//  cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN
//  but C gives  ±∞+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 imaginaryimaginary 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 imaginarydouble 用于 double imaginarylong double 用于 long double imaginary)。

注意:尽管如此,虚数类型是不同的,并且与其对应的实数类型不兼容,这禁止了别名。

虚数可以与算术运算符 + - */ 一起使用,可以与复数和实数混合使用。 <complex.h> 中为虚数定义了许多数学函数。 内置运算符和库函数都可能引发浮点异常并设置 errno,如 math_errhandling 中所述。

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

在虚数类型和其他算术类型之间定义了隐式转换

虚数使得可以使用自然表示法 x + I*y 表示所有复数(其中 I 定义为 _Imaginary_I)。 如果没有虚数类型,则某些特殊的复数值无法自然创建。 例如,如果 I 定义为 _Complex_I,则写入 0.0 + I*INFINITY 会得到 NaN 作为实部,并且必须使用 CMPLX(0.0, INFINITY)。 对于具有负零虚部的数字也是如此,当使用具有分支切割的库函数(例如 csqrt)时,这些数字是有意义的:如果 I 定义为 _Complex_I,则 1.0 - 0.0*I 导致正零虚部,而负零虚部需要使用 CMPLXconj

虚数类型还简化了实现; 如果支持虚数类型,则虚数乘以复数可以简单地用两次乘法来实现,而不是四次乘法和两次加法。

(自 C99 起)

[编辑] 关键字

[编辑] 数值范围

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

在 C23 之前,C 标准允许任何有符号整数表示,N 位有符号整数的最小保证范围为 -(2N-1
-1)
+2N-1
-1
(例如,对于有符号 8 位类型,为 -127127),这对应于 反码符号-数值表示法 的限制。

然而,所有流行的数据模型(包括 ILP32、LP32、LP64、LLP64 的所有模型)和几乎所有 C 编译器都使用 补码 表示(唯一已知的例外是一些用于 UNISYS 的编译器),并且从 C23 开始,它是标准唯一允许的表示,保证范围从 -2N-1
+2N-1
-1
(例如,对于有符号 8 位类型,为 -128127)。

类型 位大小 格式 数值范围
近似值 精确值
字符 8 signed −128127
unsigned 0255
16 UTF-16 065535
32 UTF-32 01114111 (0x10ffff)
整数 16 signed ± 3.27 · 104 −3276832767
unsigned 06.55 · 104 065535
32 signed ± 2.14 · 109 −2,147,483,6482,147,483,647
unsigned 04.29 · 109 04,294,967,295
64 signed ± 9.22 · 1018 −9,223,372,036,854,775,8089,223,372,036,854,775,807
unsigned 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[note 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−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 · 104932
  • 最小次正规数
    ±0x1p−16494
  • 最小正规数
    ±0x1p−16382
  • 最大值
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
十进制
浮点
32 IEEE-754
  • 最小次正规数
    ± 1 · 10-101
  • 最小正规数
    ± 1 · 10-95
  • 最大值
    ± 9.999'999 · 1096
64 IEEE-754
  • 最小次正规数
    ± 1 · 10-398
  • 最小正规数
    ± 1 · 10-383
  • 最大值
    ± 9.999'999'999'999'999 · 10384
128 IEEE-754
  • 最小次正规数
    ± 1 · 10-6176
  • 最小正规数
    ± 1 · 10-6143
  • 最大值
    ± 9.999'999'999'999'999'999'
    999'999'999'999'999 · 106144
  1. 对象表示通常在 32/64 位平台上分别占用 96/128 位。

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

[编辑] 参见

C++ 文档 关于 基本类型