算术类型
(另请参见类型获取类型系统概述,以及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 扩展格式;否则,匹配某些非IEEE-754 扩展浮点格式,只要其精度优于binary64且范围至少与binary64相同;否则,匹配IEEE-754 binary64 格式。
- 某些HP-UX、SPARC、MIPS、ARM64和z/OS实现使用binary128格式。
- 最著名的IEEE-754 binary64扩展格式是80位x87扩展精度格式。它被许多x86和x86-64实现使用(一个显著的例外是MSVC,它以与double相同的格式(即binary64)实现long double)。
|
(自 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。赋值、返回和强制转换会强制范围和精度与声明的类型关联。
浮点表达式也可以被“收缩”(contracted),即,计算时假设所有中间值都具有无限范围和精度,参见#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[注 1] | x86 |
|
| |
128 | IEEE-754 |
|
| |
十进制 浮点 类型 |
32 | IEEE-754 |
| |
64 | IEEE-754 |
| ||
128 | IEEE-754 |
|
- ↑ 对象表示通常在32/64位平台上分别占用96/128位。
注意:实际(而非保证最小)范围可在库头文件<limits.h>和<float.h>中获得。
[编辑] 参见
C++ 文档,关于基本类型
|