Namespaces
Variants

Arithmetic types

From cppreference.net

(另请参阅 类型 了解类型系统概述,以及 C 库提供的类型相关工具列表 。)

目录

布尔类型

  • _Bool (也可通过宏 bool 访问) (C23前) bool (C23起) — 能够持有两个值之一的类型: 1 0 (也可通过宏 true false 访问) (C23前) true false (C23起)

注意:转换为 _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
  • 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 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语言有 三种或六种 (since C23) 用于表示实浮点值的类型:

  • float — 单精度浮点类型。若支持则匹配 IEEE-754 binary32 格式
  • double — 双精度浮点类型。若支持则匹配 IEEE-754 binary64 格式
  • long double — 扩展精度浮点类型。若支持则优先匹配 IEEE-754 binary128 格式 ;否则若支持则匹配 IEEE-754 binary64 扩展格式 ;否则匹配精度优于 binary64 且范围不小于 binary64 的非 IEEE-754 扩展浮点格式;否则匹配 IEEE-754 binary64 格式。
    • binary128 格式被部分 HP-UX、SPARC、MIPS、ARM64 和 z/OS 实现所采用。
    • 最知名的 IEEE-754 binary64 扩展格式是 80 位 x87 扩展精度格式。该格式被许多 x86 和 x86-64 实现所采用(一个显著例外是 MSVC,其将 long double 实现为与 double 相同的格式,即 binary64 )。
若实现预定义了宏常量 __STDC_IEC_60559_DFP__ ,则同时支持以下十进制浮点类型:
否则,不支持这些十进制浮点类型。
(C23 起)

浮点类型可能支持特殊值:

  • infinity (正无穷与负无穷),参见 INFINITY
  • negative zero (负零), - 0.0 。其值与正零相等,但在某些算术运算中具有特殊意义,例如 1.0 / 0.0 == INFINITY ,而 1.0 / - 0.0 == - INFINITY
  • not-a-number (非数值),不与任何值相等(包括其自身)。存在多种位模式表示 NaN,参见 nan NAN 。注意 C 语言不会特别处理信号型 NaN(由 IEEE-754 定义),而是将所有 NaN 视为静默型。

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

浮点表达式可能具有比其类型所指示的更大范围和精度,详见 FLT_EVAL_METHOD 赋值 return 强制类型转换 会将范围和精度限制为与声明类型相关的范围与精度。

浮点表达式也可能被 收缩 ,即计算时如同所有中间值都具有无限范围和精度,详见 #pragma STDC FP_CONTRACT

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

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

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

复数浮点类型

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

三种复数类型包括:

注意:与所有类型说明符一样,允许任意顺序: 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__ ,则不提供复数类型(以及库头文件 <complex.h> )。

(C11起)

每种复数类型具有与对应实数类型( float 对应 float complex 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 变为 1.0 + 2.0i
memcpy(&z2, a+2, sizeof z2); // z2 变为 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);
//  教科书公式将给出
//  (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN
//  但C给出复无穷大
    printf("%f%+f*i\n", creal(z), cimag(z));
//  教科书公式将给出
//  cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN
//  但C给出 ±∞+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 三种虚数类型包括:

关键词

取值范围

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

在C23之前,C标准允许使用任何有符号整数表示方式,且N位有符号整数的最小保证范围是从 -(2 N-1
-1)
+2 N-1
-1
(例如8位有符号类型为 -127 127 ),该范围对应 反码 原码 表示的极限值。

然而,所有主流数据模型(包括ILP32、LP32、LP64、LLP64)及几乎所有C编译器均采用 二进制补码 表示法(目前已知的唯一例外是UNISYS系统的部分编译器),且自C23标准起,这成为标准唯一允许的表示方式,其保证的取值范围为 -2 N-1
+2 N-1
-1
(例如8位有符号类型的取值范围为 -128 127 )。

类型 位宽 格式 取值范围
近似值 精确值
字符型 8 有符号 −128 127
无符号 0 255
16 UTF-16 0 65535
32 UTF-32 0 1114111 ( 0x10ffff )
整型 16 有符号 ± 3.27 · 10 4 −32768 32767
无符号 0 6.55 · 10 4 0 65535
32 有符号 ± 2.14 · 10 9 −2,147,483,648 2,147,483,647
无符号 0 4.29 · 10 9 0 4,294,967,295
64 有符号 ± 9.22 · 10 18 −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
  • 最小次正规数:
    ± 1.401,298,4 · 10 −45
  • 最小正规数:
    ± 1.175,494,3 · 10 −38
  • 最大值:
    ± 3.402,823,4 · 10 38
  • 最小次正规数:
    ±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 · 10 308
  • 最小次正规数:
    ±0x1p−1074
  • 最小正规数:
    ±0x1p−1022
  • 最大值:
    ±0x1.fffffffffffffp+1023
80 [注 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
    · 10 4932
  • 最小次正规数:
    ±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 · 10 4932
  • 最小次正规数:
    ±0x1p−16494
  • 最小正规数:
    ±0x1p−16382
  • 最大值:
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
十进制
浮点型
32 IEEE-754
  • 最小次正规数:
    ± 1 · 10 -101
  • 最小正规数:
    ± 1 · 10 -95
  • 最大值:
    ± 9.999'999 · 10 96
64 IEEE-754
  • 最小次正规数:
    ± 1 · 10 -398
  • 最小正规数:
    ± 1 · 10 -383
  • 最大值:
    ± 9.999'999'999'999'999 · 10 384
128 IEEE-754
  • 最小次正规数:
    ± 1 · 10 -6176
  • 最小正规数:
    ± 1 · 10 -6143
  • 最大值:
    ± 9.999'999'999'999'999'999'
    999'999'999'999'999 · 10 6144
  1. 对象表示通常在32/64位平台上分别占用96/128位。

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

参见

C++ 文档 关于 基础类型