©
本文档使用
php.cn手册 发布
(另请参阅类型系统概述的类型以及由C库提供的与类型相关的实用程序的列表)。
_Bool
(也可以作为宏布尔) - 类型,能够保存两个值之一:1和0(也可以通过宏来访问true和false)。
请注意,conversion to _Bool与转换为其他整数类型的转换不同:(bool)0.5
评估为1
,而(int)0.5
评估为0
。
(since C99)
signed char
- 输入有符号字符表示。
unsigned char
- 输入无符号字符表示。还用于检查对象表示(原始内存)。
char
- 字符表示的类型。等同于signed char
或者unsigned char
(哪一个是实现定义的,并且可以由编译器命令行开关控制),但是char
是不同的类型,不同于signed char
两者unsigned char
请注意,标准库还定义了用于表示宽字符的typedef名称wchar_t,char16_t和char32_t(自C11起)。
short int
(也可以访问short
,可以使用关键字signed
)
unsigned short int
(也可以访问unsigned short
)
int
(也可以访问signed int
)
unsigned int
(也可以访问unsigned
)int
,实现模运算的未签名对应方。适用于位操作。
long int
(也可以访问long
)
unsigned long int
(也可以访问unsigned long
)
这是该平台的最佳整数类型,并且保证至少为16位。大多数当前系统使用32位(请参见下面的数据模型)。
long long int
(也可以访问long long
)
unsigned long long int
(也可以访问unsigned long long
)
(since C99)
注意:与所有类型说明符一样,任何次序都是允许的:unsigned long long int
与long int unsigned long
命名相同的类型。
下表总结了所有可用的整数类型及其属性:
类型说明符 | 等效类型 | 数据模型的位宽 | ||||
---|---|---|---|---|---|---|
C标准 | LP32 | ILP32 | LLP64 | LP64 | ||
短 | 短整型 | 至少为16 | 16 | 16 | 16 | 16 |
除了最小的位数外,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位长,指针是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位长,指针是64位)
Unix和类Unix系统(Linux,Mac OS X)
其他型号非常少见。例如,ILP64(8/8/8:int,long和指针是64位)仅出现在一些早期的64位Unix系统中(例如Cray上的Unicos)。
请注意,自C99开始,精确宽度的整数类型在<stdint.h>中可用。
C有三种类型来表示实际的浮点值:
float
- 单精度浮点型。如果支持,匹配IEEE-754 32位浮点类型。
double
- 双精度浮点型。如果支持,匹配IEEE-754 64位浮点类型
long double
- 扩展精度浮点类型。如果支持,则匹配IEEE-754扩展浮点类型,否则匹配某些非标准扩展浮点类型,只要其精度优于double
且范围至少与double
一致,否则匹配类型double
。一些x86和x86_64实现使用80位x87浮点类型。
浮点类型可能支持特殊值:
无限(正面和负面),见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
三种复杂类型是
float _Complex
(也可以像float
complex
包含<complex.h>一样使用)
double _Complex
(也可以像double
complex
包含<complex.h>一样使用)
long double _Complex
(也可以像long
double
complex
包含<complex.h>一样使用)
注意:与所有类型说明符一样,可以使用任何顺序:long
double
complex
,complex
long
double
甚至double
complex
long
命名相同的类型。
运行此代码
#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
如果宏常量__STDC_NO_COMPLEX__
(C11)由实现定义,<complex.h>
则不提供复杂类型(以及库标题)。(自C11以来)
每个复杂类型具有相同的对象表示和对准要求作为一个阵列对应的真实类型的两个元件(的浮动为float compelx,double为double complex,long double为long double complex)。数组的第一个元素保存实数部分,数组的第二个元素保存虚数部分。
float a[4] = {1, 2, 3, 4};float complex z1, z2;memcpy(&z1, a, sizeof z1); // z1 becomes 1.0 + 2.0imemcpy(&z2, a+2, sizeof z2); // z2 becomes 3.0 + 4.0i
复数可能与算术运算符+ - 和*一起使用,可能与虚数和实数混合使用。在complex.h中为复数定义了许多数学函数。内置运算符和库函数都可能会引发浮点异常并errno
按照math_errhandling
中所述进行设置。
没有为复杂类型定义增量和减量。
没有为复杂类型定义关系运算符(没有“小于”的概念)在复杂类型和其他算术类型之间定义隐式转换。
为了支持复数运算的单一无穷大模型,C 将具有至少一个无限部分的任何复数值视为无穷大,即使其另一部分是 NaN,也保证所有运算符和函数都遵守入口的基本属性并提供cproj
将所有无穷大映射到规范的一个(请参阅算术运算符以了解确切的规则)。
运行此代码
#include <stdio.h>#include <complex.h>#include <math.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 + i*%f\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 + i*%f\n", creal(y), cimag(y));
可能的输出:
inf + i*inf inf + i*nan
C 尽管存在笛卡尔表示的内在局限性,但它也可以处理多个无穷大,以尽可能地保留方向信息:
将虚数单位乘以实无穷大给出正确签名的虚无限:i×∞=i∞。另外,i×(∞-i∞)=∞+i∞表示合理的象限。
虚浮点类型
虚浮点类型对数学虚数进行建模,即可以写成实数乘以虚数单位的数字:bi 三个虚构类型。
float _Imaginary
(也可以像float
imaginary
包含<complex.h>一样使用)
double _Imaginary
(也可以像double
imaginary
包含<complex.h>一样使用)
long double _Imaginary
(也可以像long
double
imaginary
包含<complex.h>一样使用)
注意:与所有类型说明符一样,可以使用任何顺序:long
double
imaginary
,imaginary
long
double
甚至double
imaginary
long
命名相同的类型。
#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
建议定义__STDC_IEC_559_COMPLEX__的编译器,但不要求支持虚数。POSIX建议检查宏_Imaginary_I是否被定义为标识虚数支持。(自C99开始)(直到C11)
如果__STDC_IEC_559_COMPLEX__
定义了虚数,则支持虚数。(自 C11开始)
三种虚构类型中的每一种都具有与其对应的真实类型(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)
必须使用 NaN 。具有负零虚数分量的数字也是如此,当使用分支切分处理库函数时这些数字是有意义的,例如csqrt
:1.0 - 0.0*I
如果I
定义为正零零虚数分量,_Complex_I
并且负零虚数部分需要使用CMPLX
或conj
。
虚构类型也简化了实现; 如果虚数类型得到支持,则可以用两次乘法直接实现虚数与复数的乘法,而不是四次乘法和两次加法。
(since C99)
char
, int
, short
, long
, signed
, unsigned
, float
, double
. _Bool
, _Complex
, _Imaginary
.
下表提供了常用数字表示限制的参考。由于 C 标准允许任何带符号的整数表示,因此该表给出了最小保证需求(对应于补码的限制或符号和幅度)以及最常用的实现的限制,即二进制补码。不过,所有流行的数据模型(包括 ILP32,LP32,LP64,LLP64)都使用二进制补码表示法。
类型 | 大小以位为单位 | 格式 | 值范围 | |
---|---|---|---|---|
近似 | 精确值 | |||
字符 | 8 | signed (补充) | -127至127 | |
signed (二补) | -128至127 | |||
无符号 | 0到255 | |||
积分 | 16 | signed (补充) | ± 3.27 · 104 | -32767至32767 |
signed (二补) | -32768至32767 | |||
无符号 | 0至6.55·104 | 0至65535 | ||
32 | signed (补充) | ± 2.14 · 109 | -2,147,483,647至2,147,483,647 | |
signed (二补) | -2,147,483,648至2,147,483,647 | |||
无符号 | 0至4.29·109 | 0至4,294,967,295 | ||
64 | signed (补充) | ± 9.22 · 1018 | -9,223,372,036,854,775,807至9,223,372,036,854,775,807 | |
signed (二补) | -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 | ±3.4·10±38(〜7位) | min低于正常值:±1.401,298,4·10-47分钟正常值:±1.175,494.3·10-38最高值:±3.402,823,4.1038 |
64 | IEEE-754 | ±1.7·10±308(〜15位) | min低于正常值:±4.940,656,458,412·10-324分钟正常值:±2.225,073,858,507,201,4·10-308最大值:±1.797,693,134,862,315,7·10308 |
次正常:±1,401,298.4·10-47
分钟正常值:±1.175,494.3·10-38
最大值:±3.402,823,4.1038
64 IEEE-754 **± 1.7 · 10± 308**
(~15 digits)
次正常分:±4,940,656,458,412·10-324
分钟正常值:±2.225,073,858,507,201,4·10-308
最大:±1.797,693,134,862,315,7·10308
注意:库头文件<limits.h>和<float.h>中提供了实际的(而不是保证的最小值)范围