算术类型
(可参阅类型,以获得类型系统综述,及 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 起) 以表示宽字符,以及表示 UTF-8 字符的 char8_t(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 扩展格式,否则匹配某种精度优于 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 相同的格式,即 binary64)。
|
(C23 起) |
浮点数类型可以支持特殊值:
- 无穷大(正与负),见 INFINITY
- 负零,-0.0。它与正零比较相等,但对于某些算术运算有意义(例如 1.0/0.0 == INFINITY,但 1.0 / -0.0 == -INFINITY)。
- 非数(NaN),它与任何值比较不相等(包括其自身)。有多种位模式表示 NaN,见 nan、NAN。注意 C 对(IEEE-754 所指定的)NaN 信号不作任何留意,并安静处理所有 NaN。
实浮点数可与算术运算符 +
-
/
*
和来自 <math.h> 的大量数学函数一同使用。内建运算符和库函数都可能引发浮点数异常,并以 math_errhandling 中描述的方式设置 errno。
浮点数表达式可拥有大于其类型所指示的范围和精度,见 FLT_EVAL_METHOD。赋值、return 和转型强制将范围和精度变成声明类型所关联者。
浮点数表达式亦可被缩略,即仿佛中间值拥有无限范围和精度一般计算,见 #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); // 教科书公式会给出 // (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、 |