C
C 语法

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 intlong int unsigned long命名相同的类型。

下表总结了所有可用的整数类型及其属性:

类型说明符等效类型数据模型的位宽
C standard
shortshort intat least 16
short int
signed short
signed short int
unsigned shortunsigned short int
unsigned short int
intintat least 16
signed
signed int
unsignedunsigned int
unsigned int
longlong intat least 32
long int
signed long
signed long int
unsigned longunsigned long int
unsigned long int
long longlong long intat least 64
long long int
signed long long
signed long long int
unsigned long longunsigned 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位系统:

  • LP322/4/4(int是16位长,指针是32位)

64位系统:

  • LLP644/4/8(int和long是32位,指针是64位)

其他型号非常少见。例如,ILP648/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 complexcomplex 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 imaginaryimaginary 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 imaginarydouble double imaginarylong 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 。具有负零虚数分量的数字也是如此,当使用分支切分处理库函数时这些数字是有意义的,例如csqrt1.0 - 0.0*I如果I定义为正零零虚数分量,_Complex_I并且负零虚数部分需要使用CMPLXconj

虚构类型也简化了实现; 如果虚数类型得到支持,则可以用两次乘法直接实现虚数与复数的乘法,而不是四次乘法和两次加法。

(since C99)

关键词

char, int, short, long, signed, unsigned, float, double. _Bool, _Complex, _Imaginary.

值的范围

下表提供了常用数字表示限制的参考。由于 C 标准允许任何带符号的整数表示,因此该表给出了最小保证需求(对应于补码的限制或符号和幅度)以及最常用的实现的限制,即二进制补码。不过,所有流行的数据模型(包括 ILP32,LP32,LP64,LLP64)都使用二进制补码表示法。

类型大小以位为单位格式值范围
近似精确
字符8signed(补充)-127至127
signed(二补)-128至127
无符号0到255
积分16signed(补充)±3.27·10∧4-32767至32767
signed(二补)-32768至32767
无符号0至6.55·10∧40至65535
32signed(补充)±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∧90至4,294,967,295
64signed(补充)±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∧190至18,446,744,073,709,551,615
浮动32IEEE-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
64IEEE-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>中提供了实际的(而不是保证的最小值)范围