Arithmetic types
算术类型
(另请参阅类型系统概述的类型以及由C库提供的与类型相关的实用程序的列表)。
_Bool
(也可以作为宏布尔) - 类型,能够保存两个值之一:1和0(也可以通过宏来访问true和false)。
请注意,conversion to _Bool与转换为其他整数类型的转换不同:(bool)0.5
评估为1
,而(int)0.5
评估为0
。
(since C99)
字符类型
signed char
- 输入有符号字符表示。
请注意,标准库还定义了用于表示宽字符的typedef名称wchar_t,char16_t和char32_t(自C11起)。
整数类型
short int
(也可以访问short
,可以使用关键字signed
)
这是该平台的最佳整数类型,并且保证至少为16位。大多数当前系统使用32位(请参见下面的数据模型)。
long long int
(也可以访问long long
)
(since C99)
注意:与所有类型说明符一样,任何次序都是允许的:unsigned long long int
与long int unsigned long
命名相同的类型。
下表总结了所有可用的整数类型及其属性:
类型说明符 | 等效类型 | 数据模型的位宽 |
---|---|---|
C standard | ||
short | short int | at least 16 |
short int | ||
signed short | ||
signed short int | ||
unsigned short | unsigned short int | |
unsigned short int | ||
int | int | at least 16 |
signed | ||
signed int | ||
unsigned | unsigned int | |
unsigned int | ||
long | long int | at least 32 |
long int | ||
signed long | ||
signed long int | ||
unsigned long | unsigned long int | |
unsigned long int | ||
long long | long long int | at least 64 |
long long int | ||
signed long long | ||
signed long long int | ||
unsigned long long | unsigned long long int | |
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位长,指针是32位)
64位系统:
LLP64
或4/4/8
(int和long是32位,指针是64位)
其他型号非常少见。例如,ILP64
(8/8/8
:int,long和指针是64位)仅出现在一些早期的64位Unix系统中(例如Cray上的Unicos)。
请注意,自C99开始,精确宽度的整数类型在<stdint.h>中可用。
真正的浮动类型
C有三种类型来表示实际的浮点值:
float
- 单精度浮点型。如果支持,匹配IEEE-754 32位浮点类型。
浮点类型可能支持特殊值:
无限
(正面和负面),见INFINITY
实数浮点数可能与算术运算符+ - / *和math.h中的各种数学函数一起使用。内置运算符和库函数都可能会引发浮点异常且errno
按照math_errhandling
中所述进行设置。
请参阅,浮点表达式的范围和精度可能比其类型所指示的范围和精度要高于FLT_EVAL_METHOD
。赋值,返回和强制将范围和精度强制为与声明类型关联的范围和精度。
浮点表达式也可能会收缩
,就像所有中间值具有无限范围和精度一样计算,请参阅#pragma STDC FP_CONTRACT。
浮点数的一些操作受浮点环境的状态(最显着的是舍入方向)的影响和修改。
隐式转换定义在实际浮点类型与整数,复数和虚数类型之间。
有关浮点类型的其他详细信息,限制和属性,请参阅浮点类型的限制和math.h库。
- float _Complex(也可以像float complex包含<complex.h>一样使用)
注意:与所有类型说明符一样,可以使用任何顺序:long
double
complex
,complex
long
double
甚至double
complex
long
命名相同的类型。
运行此代码
输出:
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 becomes 1.0 + 2.0i
memcpy(&z2, a+2, sizeof z2 // z2 becomes 3.0 + 4.0i
复数可能与算术运算符+ - 和*一起使用,可能与虚数和实数混合使用。在complex.h中为复数定义了许多数学函数。内置运算符和库函数都可能会引发浮点异常并errno
按照math_errhandling
中所述进行设置。
没有为复杂类型定义增量和减量。
没有为复杂类型定义关系运算符(没有“小于”的概念)在复杂类型和其他算术类型之间定义隐式转换。
为了支持复数运算的单一无穷大模型,C 将具有至少一个无限部分的任何复数值视为无穷大,即使其另一部分是 NaN,也保证所有运算符和函数都遵守入口的基本属性并提供cproj
将所有无穷大映射到规范的一个(请参阅算术运算符以了解确切的规则)。
运行此代码
可能的输出:
inf + i*inf
inf + i*nan
C 尽管存在笛卡尔表示的内在局限性,但它也可以处理多个无穷大,以尽可能地保留方向信息:
将虚数单位乘以实无穷大给出正确签名的虚无限:i×∞=i∞。另外,i×(∞-i∞)=∞+i∞表示合理的象限。
虚浮点类型
虚浮点类型对数学虚数进行建模,即可以写成实数乘以虚数单位的数字:bi 三个虚构类型。
- float _Imaginary(也可以像float 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·10∧4 | -32767至32767 |
signed(二补) | -32768至32767 | |||
无符号 | 0至6.55·10∧4 | 0至65535 | ||
32 | signed(补充) | ±2.14·10∧9 | -2,147,483,647至2,147,483,647 | |
signed(二补) | -2,147,483,648至2,147,483,647 | |||
无符号 | 0至4.29·10∧9 | 0至4,294,967,295 | ||
64 | signed(补充) | ±9.22·10∧18 | -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 | |||
无符号 | 0至1.84·10∧19 | 0至18,446,744,073,709,551,615 | ||
浮动 | 32 | IEEE-754 | ±3.4·10 ∧(±38) (~7 digits) | min 低于正常值:±1.401,298,4·10 -47 |
min正常值:±1.175,494.3·10 -38 | ||||
最大值:±3.402,823,4·10 38 | ||||
64 | IEEE-754 | ±1.7·10∧(±308) (~15 digits) | min 低于正常值:±4.940,656,458,412·10 -324 | |
min正常值:±2.225,073,858,507,201,4·10 -308 | ||||
最大:±1.797,693,134,862,315,7·10 308 |
- 次正常:
±1,401,298.4·10-47
64 IEEE-754 **± 1.7 · 10± 308**
(~15 digits)
- 次正常分:
±4,940,656,458,412·10-324
注意:库头文件<limits.h>和<float.h>中提供了实际的(而不是保证的最小值)范围