命名空间
变体
操作

算术类型

来自 cppreference.com
< c‎ | 语言

(另请参阅 类型 以了解类型系统概述,以及 C 库提供的与类型相关的实用程序列表。)

内容

布尔类型

  • _Bool (也可以通过宏 bool 访问)(直到 C23)bool(自 C23 起) - 类型,可以保存两个值之一:10 (也可以通过宏 truefalse 访问)(直到 C23)truefalse(自 C23 起).

请注意,转换为 _Bool(直到 C23)bool(自 C23 起) 的方式与转换为其他整数类型的方式不同:(bool)0.5 评估为 true,而 (int)0.5 评估为 0.

(自 C99 起)

[编辑] 字符类型

  • signed char - 用于有符号字符表示的类型。
  • unsigned char - 用于无符号字符表示的类型。也用于检查 对象表示 (原始内存)。
  • char - 用于字符表示的类型。等效于 signed charunsigned char (哪一个是实现定义的,可以通过编译器命令行开关控制),但 char 是一个不同的类型,不同于 signed charunsigned char

请注意,标准库还定义了 typedef 名称 wchar_t , char16_tchar32_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 访问)
  • long long int (也可以通过 long long 访问)
  • unsigned long long int (也可以通过 unsigned long long 访问)
(自 C99 起)
  • _BitInt(n) (也可以通过 signed _BitInt(n) 访问),位精确的有符号整数类型(其中 n 被替换为表示精确宽度(包括符号位)的整数常量表达式,该表达式不能大于来自 <limits.h>BITINT_MAXWIDTH
  • unsigned _BitInt(n),位精确的无符号整数类型(其中 n 被替换为表示精确宽度的整数常量表达式,该表达式不能大于来自 <limits.h>BITINT_MAXWIDTH
(自 C23 起)

注意:与所有类型说明符一样,允许任何顺序:unsigned long long intlong 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 位系统

  • LP322/4/4(int 为 16 位,long 和指针为 32 位)
  • Win16 API
  • ILP324/4/4(int、long 和指针为 32 位);
  • Win32 API
  • Unix 和类 Unix 系统(Linux、Mac OS X)

64 位系统

  • LLP644/4/8(int 和 long 为 32 位,指针为 64 位)
  • Win64 API
  • LP644/8/8(int 为 32 位,long 和指针为 64 位)
  • Unix 和类 Unix 系统(Linux、Mac OS X)

其他模型非常罕见。例如,ILP648/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-extended 格式 匹配,否则与某些非 IEEE-754 扩展浮点格式匹配,只要其精度比 binary64 好且范围至少与 binary64 一样好,否则与 IEEE-754 binary64 格式匹配。
    • binary128 格式被一些 HP-UX、SPARC、MIPS、ARM64 和 z/OS 实现使用。
    • 最著名的 IEEE-754 binary64-extended 格式是 80 位 x87 扩展精度格式。它被许多 x86 和 x86-64 实现使用(一个显著的例外是 MSVC,它将 long double 实现为与 double 相同的格式,即 binary64)。
如果实现预定义了宏常量 __STDC_IEC_60559_DFP__,则还支持以下十进制浮点类型。
否则,不支持这些十进制浮点类型。
(自 C23 起)

浮点类型可能支持特殊值

  • 无穷大(正负),请参阅 INFINITY
  • 负零-0.0。它与正零比较相等,但在某些算术运算中是有意义的,例如 1.0/0.0 == INFINITY,但 1.0/-0.0 == -INFINITY)
  • 非数(NaN),它不与任何事物(包括自身)比较相等。多个位模式表示 NaN,请参阅 nanNAN。注意,C 不会对信号 NaN(由 IEEE-754 指定)采取任何特殊措施,并将所有 NaN 视为静默的。

实浮点数可以与 算术运算符 + - / * 和 <math.h> 中的各种数学函数一起使用。内置运算符和库函数都可能引发浮点异常并设置 errno,如 math_errhandling 中所述。

浮点表达式可能具有比其类型指示的更大的范围和精度,请参阅 FLT_EVAL_METHOD赋值返回强制转换 将范围和精度强制为与声明类型关联的范围和精度。

浮点表达式也可能被压缩,也就是说,它们被计算为所有中间值具有无限范围和精度,请参阅 #pragma STDC FP_CONTRACT

浮点数上的一些操作会受到 浮点环境 状态的影响并修改其状态(最显著的是舍入方向)。

隐式转换 在实浮点类型和整数、复数和虚数类型之间定义。

请参阅 浮点类型限制<math.h> 库以获取有关浮点类型更多详细信息、限制和属性。

复浮点类型

复浮点类型模拟数学上的 复数,即可以写成实数加上虚数单位乘以实数的数:a + bi

三种复数类型是

注意:与所有类型说明符一样,任何顺序都是允许的:long double complexcomplex 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__ 由实现定义,则不提供复数类型(以及库头文件 <complex.h>)。

(自 C11 起)

每个复数类型都具有与对应实数类型(float 用于 float complexdouble 用于 double complexlong 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.0i
memcpy(&z2, a+2, sizeof z2); // z2 becomes 3.0 + 4.0i

复数可以与 算术运算符 + - * 和 / 一起使用,可能与虚数和实数混合使用。<complex.h> 中为复数定义了许多数学函数。内置运算符和库函数都可能引发浮点异常并设置 errno,如 math_errhandling 中所述。

复数类型未定义递增和递减。

复数类型未定义关系运算符(没有“小于”的概念)。

隐式转换 在复数类型和其他算术类型之间定义。

为了支持复数运算的单无穷大模型,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 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 是否已定义来识别虚数支持。

(直到 C11)

如果定义了 __STDC_IEC_559_COMPLEX__(直到 C23)__STDC_IEC_60559_COMPLEX__(自 C23 起),则支持虚数。

(自 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)。 同样适用于具有负零虚数部分的数字,这些数字在使用具有分支切割的库函数(例如 csqrt)时很有意义:1.0 - 0.0*I 如果 I 定义为 _Complex_I 则会产生正零虚数部分,而负零虚数部分需要使用 CMPLXconj

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

(自 C99 起)

[edit] 关键字

[edit] 值的范围

下表提供了对常见数字表示范围的参考。

在 C23 之前,C 标准允许任何有符号整数表示,并且 N 位有符号整数的最小保证范围是从 -(2N-1
-1)
+2N-1
-1
(例如,对于 8 位有符号类型,-127127),这对应于 一补码符号幅度 的限制。

但是,所有流行的数据模型(包括所有 ILP32、LP32、LP64、LLP64)和几乎所有 C 编译器都使用 二进制补码 表示(唯一已知的例外是一些 UNISYS 的编译器),并且从 C23 开始,它是标准允许的唯一表示,保证的范围是从 -2N-1
+2N-1
-1
(例如,对于 8 位有符号类型,-128127)。

类型 位数 格式 值范围
大约 准确
字符 8 signed −128127
unsigned 0255
16 UTF-16 065535
32 UTF-32 01114111 (0x10ffff)
整数 16 signed ± 3.27 · 104 −3276832767
unsigned 06.55 · 104 065535
32 signed ± 2.14 · 109 −2,147,483,6482,147,483,647
unsigned 04.29 · 109 04,294,967,295
64 signed ± 9.22 · 1018 −9,223,372,036,854,775,8089,223,372,036,854,775,807
unsigned 01.84 · 1019 018,446,744,073,709,551,615
二进制
浮点
32 IEEE-754
  • 最小次正规数
    ± 1.401,298,4 · 10−45
  • 最小正规数
    ± 1.175,494,3 · 10−38
  • 最大
    ± 3.402,823,4 · 1038
  • 最小次正规数
    ±0x1p−149
  • 最小正规数
    ±0x1p−126
  • 最大
    ±0x1.fffffep+127
64 IEEE-754
  • 最小次正规数
    ± 4.940,656,458,412 · 10−324
  • 最小正规数
    ± 2.225,073,858,507,201,4 · 10−308
  • 最大
    ± 1.797,693,134,862,315,7 · 10308
  • 最小次正规数
    ±0x1p−1074
  • 最小正规数
    ±0x1p−1022
  • 最大
    ±0x1.fffffffffffffp+1023
80[note 1] x86
  • 最小次正规数
    ± 3.645,199,531,882,474,602,528
     · 10−4951
  • 最小正规数
    ± 3.362,103,143,112,093,506,263
     · 10−4932
  • 最大
    ± 1.189,731,495,357,231,765,021
     · 104932
  • 最小次正规数
    ±0x1p−16445
  • 最小正规数
    ±0x1p−16382
  • 最大
    ±0x1.fffffffffffffffep+16383
128 IEEE-754
  • 最小次正规数
    ± 6.475,175,119,438,025,110,924,
    438,958,227,646,552,5 · 10−4966
  • 最小正规数
    ± 3.362,103,143,112,093,506,262,
    677,817,321,752,602,6 · 10−4932
  • 最大
    ± 1.189,731,495,357,231,765,085,
    759,326,628,007,016,2 · 104932
  • 最小次正规数
    ±0x1p−16494
  • 最小正规数
    ±0x1p−16382
  • 最大
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
十进制
浮点
32 IEEE-754
  • 最小次正规数
    ± 1 · 10-101
  • 最小正规数
    ± 1 · 10-95
  • 最大
    ± 9.999'999 · 1096
64 IEEE-754
  • 最小次正规数
    ± 1 · 10-398
  • 最小正规数
    ± 1 · 10-383
  • 最大
    ± 9.999'999'999'999'999 · 10384
128 IEEE-754
  • 最小次正规数
    ± 1 · 10-6176
  • 最小正规数
    ± 1 · 10-6143
  • 最大
    ± 9.999'999'999'999'999'999'
    999'999'999'999'999 · 106144
  1. 对象表示通常在 32/64 位平台上分别占用 96/128 位。

注意:实际(与保证的最小范围相反)范围在库头文件 <limits.h><float.h> 中可用。

[edit] 另请参阅

C++ 文档 对于 基本类型