算术类型
(可参阅类型,以获得类型系统综述,及 C 库提供的类型相关工具列表。)
布尔类型注意,到 _Bool(C23 前)bool(C23 起) 的转换与到其他整数类型的转换不同: |
(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)
- LP32 或 2/4/4 (
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)
- LLP64 或 4/4/8 (
其他数据模型非常罕见。例如,ILP64(8/8/8:int、long 及指针均为 64 位)仅出现于某些早期 64 位 Unix 系统(例如 Cray 上的 Unicos)。
注意从 C99 开始可从 <stdint.h> 中使用准确宽度的整数。
实浮点数类型
C 拥有三或六(C23 起)种表示实浮点数的类型:
float— 单精度浮点数类型。若支持则匹配 IEEE-754binary32格式。double— 双精度浮点数类型。若支持则匹配 IEEE-754binary64格式。long double— 扩展精度浮点数类型。若支持则匹配 IEEE-754binary128格式,否则若支持则匹配 IEEE-754 binary64 扩展格式,否则匹配某种精度优于binary64而值域至少和binary64一样好的非 IEEE-754 扩展浮点数格式,否则匹配 IEEE-754binary64格式。- 一些 HP-UX、 SPARC、 MIPS、 ARM64 和 z/OS 实现使用
binary128格式。 - 最知名的 IEEE-754
binary64扩展格式是 80 位 x87 扩展精度格式。许多 x86 和 x86-64 实现使用它(一个典型的例外是 MSVC ,它将long double实现为与double相同的格式,即binary64)。
- 一些 HP-UX、 SPARC、 MIPS、 ARM64 和 z/OS 实现使用
|
(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 三种复数类型是
注意:同所有类型说明符,允许任意顺序: 运行此代码 #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
每个复数类型均与拥有两个对应实数类型( 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复数可用于算术运算符 复数类型中不定义自增和自减。 复数类型中不定义关系运算符(没有“小于”的记号)。
隐式转换定义于复数类型和其他算术类型。 为支持复数算术的一个无限模型, 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*iC 也会处理多重无穷大,以在可能的地方保留方向信息,不管笛卡尔表示的固有限制: 实无穷大乘虚数单位,会给出对应符号的虚无穷大: i × ∞ = i∞ 。同理, i × (∞ – i∞) = ∞ + i∞ 指示合理的象限。
虚浮点数类型虚浮点数类型模仿数学的虚数,即可以写成实数乘虚数单位的数:bi 三种虚数类型是
注意:同所有类型说明符,允许任意顺序: 运行此代码 #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
三种虚数类型各拥有与其对应实数类型( 注意:尽管如此,虚数类型是独立的,且与其对应实数类型不兼容,这禁止别名使用。 虚数可用于 算术运算符 自增和自减不定义于虚数类型。
隐式转换定义于虚数类型和其他算术类型之间。 虚数类型零通过自然记号 虚数类型亦会简化实现:若支持虚数则复数乘虚数可以直接实现为二次乘法,而非四次乘法和二次加法。 |
(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 | 有符号 | -128 到 127 | |
| 无符号 | 0 到 255 | |||
| 16 | UTF-16 | 0 到 65535 | ||
| 32 | UTF-32 | 0 到 1114111 (0x10ffff) | ||
| 整数 | 16 | 有符号 | ± 3.27 · 104 | -32768 到 32767 |
| 无符号 | 0 到 6.55 · 104 | 0 到 65535 | ||
| 32 | 有符号 | ± 2.14 · 109 | -2,147,483,648 到 2,147,483,647 | |
| 无符号 | 0 到 4.29 · 109 | 0 到 4,294,967,295 | ||
| 64 | 有符号 | ± 9.22 · 1018 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | |
| 无符号 | 0 到 1.84 · 1019 | 0 到 18,446,744,073,709,551,615 | ||
| 二进制浮点数 | 32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
| |
| 80[注 1] | x86 |
|
| |
| 128 | IEEE-754 |
|
| |
| 十进制浮点数 | 32 | IEEE-754 |
| |
| 64 | IEEE-754 |
| ||
| 128 | IEEE-754 |
| ||
- ↑ 在 32/64 位平台上对象表示通常占用 96/128 位。
注意:实际(与保证最小值相对)的范围可在库头文件 <limits.h> 和 <float.h> 中获得。
参阅
基础类型的 C++ 文档
|