算术类型
(另请参阅 类型 以了解类型系统概述,以及 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,它将 long double 实现为与 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 视为静默的。
实浮点数可以与 算术运算符 + - / * 和 <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)的两个元素的 数组 相同的 对象表示 和 对齐要求。数组的第一个元素保存实部,数组的第二个元素保存虚部。 复数可以与 算术运算符 + - * 和 / 一起使用,可能与虚数和实数混合使用。<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 imaginary,imaginary long double,甚至 double imaginary long 指的是相同的类型。 运行此代码 输出 1/(3.0i) = -0.3i
三种虚数类型中的每一种都具有与相应的实数类型相同的 对象表示 和 对齐要求(float 用于 float imaginary,double 用于 double imaginary,long 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)时很有意义:1.0 - 0.0*I 如果 I 定义为 _Complex_I 则会产生正零虚数部分,而负零虚数部分需要使用 CMPLX 或 conj。 虚数类型也简化了实现; 如果支持虚数类型,则虚数与复数的乘法可以通过两次乘法直接实现,而不是四次乘法和两次加法。 |
(自 C99 起) |
[edit] 关键字
- bool,true,false,char,int,short,long,signed,unsigned,float,double。
- _Bool,_BitInt,_Complex,_Imaginary,_Decimal32,_Decimal64,_Decimal128。
[edit] 值的范围
下表提供了对常见数字表示范围的参考。
在 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> 中可用。
[edit] 另请参阅
C++ 文档 对于 基本类型
|