算术类型
(另见 类型 以获取类型系统概述,以及 C 库提供的类型相关实用工具列表。)
布尔类型请注意,转换为 _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 访问)
|
(自 C99 起) |
|
(自 C23 起) |
注意:与所有类型说明符一样,允许任何顺序:unsigned long long int 和 long 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 位系统
- 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-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)。
|
(自 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 complex、complex long double,甚至 double complex long 指的是相同的类型。 运行此代码 输出 1/(1.0+2.0i) = 0.2-0.4i
每种复数类型都具有与相应实数类型的两个元素的数组相同的对象表示和 对齐要求(float 用于 float complex,double 用于 double complex,long double 用于 long double complex)。 数组的第一个元素保存实部,数组的第二个元素保存虚部。 复数可以与算术运算符 未为复数类型定义递增和递减。 未为复数类型定义关系运算符(没有“小于”的概念)。
为了支持复数算术的单无穷模型,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 imaginary、imaginary long double,甚至 double imaginary long 指的是相同的类型。 运行此代码 输出 1/(3.0i) = -0.3i
三种虚数类型中的每一种都具有与其相应的实数类型相同的对象表示和 对齐要求(float 用于 float imaginary,double 用于 double imaginary,long double 用于 long double imaginary)。 注意:尽管如此,虚数类型是不同的,并且与其对应的实数类型不兼容,这禁止了别名。 虚数可以与算术运算符 未为虚数类型定义递增和递减。
虚数使得可以使用自然表示法 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 导致正零虚部,而负零虚部需要使用 CMPLX 或 conj。 虚数类型还简化了实现; 如果支持虚数类型,则虚数乘以复数可以简单地用两次乘法来实现,而不是四次乘法和两次加法。 |
(自 C99 起) |
[编辑] 关键字
- bool, true, false, char, int, short, long, signed, unsigned, float, double。
- _Bool, _BitInt, _Complex, _Imaginary, _Decimal32, _Decimal64, _Decimal128。
[编辑] 数值范围
下表提供了常用数值表示的范围参考。
在 C23 之前,C 标准允许任何有符号整数表示,N 位有符号整数的最小保证范围为 -(2N-1
-1) 到 +2N-1
-1 (例如,对于有符号 8 位类型,为 -127 到 127),这对应于 反码 或 符号-数值表示法 的限制。
然而,所有流行的数据模型(包括 ILP32、LP32、LP64、LLP64 的所有模型)和几乎所有 C 编译器都使用 补码 表示(唯一已知的例外是一些用于 UNISYS 的编译器),并且从 C23 开始,它是标准唯一允许的表示,保证范围从 -2N-1
到 +2N-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 · 104 | −32768 到 32767 |
unsigned | 0 到 6.55 · 104 | 0 到 65535 | ||
32 | signed | ± 2.14 · 109 | −2,147,483,648 到 2,147,483,647 | |
unsigned | 0 到 4.29 · 109 | 0 到 4,294,967,295 | ||
64 | signed | ± 9.22 · 1018 | −9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | |
unsigned | 0 到 1.84 · 1019 | 0 到 18,446,744,073,709,551,615 | ||
二进制 浮点 数 |
32 | IEEE-754 |
|
|
64 | IEEE-754 |
|
| |
80[note 1] | x86 |
|
| |
128 | IEEE-754 |
|
| |
十进制 浮点 数 |
32 | IEEE-754 |
| |
64 | IEEE-754 |
| ||
128 | IEEE-754 |
|
- ↑ 对象表示通常在 32/64 位平台上分别占用 96/128 位。
注意:实际(相对于保证的最小值)范围可在库头文件 <limits.h> 和 <float.h> 中找到。
[编辑] 参见
C++ 文档 关于 基本类型
|