非常教程

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 - 输入有符号字符表示。
  • 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(也可以访问unsignedint,实现模运算的未签名对应方。适用于位操作。
  • 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 intlong int unsigned long命名相同的类型。

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

类型说明符

等效类型

数据模型的位宽

C standard

LP32

ILP32

LLP64

LP64

short

short int

at least 16

16

16

16

16

short int

signed short

signed short int

unsigned short

unsigned short int

unsigned short int

int

int

at least 16

16

32

32

32

signed

signed int

unsigned

unsigned int

unsigned int

long

long int

at least 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

at least 64

64

64

64

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位系统:

  • LP322/4/4(int是16位长,指针是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位长,指针是64位)
    • Unix和类Unix系统(Linux,Mac OS X)

其他型号非常少见。例如,ILP648/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的,参阅nanNAN。请注意,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 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__(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.0i
memcpy(&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 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)都使用二进制补码表示法。

类型

大小以位为单位

格式

值范围

近似

精确

字符

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
  • 分钟正常值:±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>中提供了实际的(而不是保证的最小值)范围

C 语法相关

1.#define directive
2.#elif directive
3.#else directive
4.#endif directive
5.#error directive
6.#if directive
7.#ifdef directive
8.#ifndef directive
9.#include directive
10.#line directive
11.#pragma directive
12.alignas
13.Alternative operators and tokens
14.Analyzability
15.Arithmetic operators
16.Array declaration
17.Array initialization
18.ASCII Chart
19.Assignment operators
20. types
21.Basic concepts
22.Bit fields
23.break statement
24.C language
25.C Operator Precedence
26.cast operator
27.character constant
28.Comments
29.Comparison operators
30.compound literals
31.Conditional inclusion
32.Conformance
33.const type qualifier
34.Constant expressions
35.continue statement
36.Declarations
37.do-while loop
38.Enumerations
39.Escape sequences
40.Expressions
41.External and tentative definitions
42.File scope
43.floating constant
44.for loop
45.Function declarations
46.Function definitions
47.Functions
48.Generic selection
49.goto statement
50.Identifier
51.if statement
52.Implicit conversions
53.Increment/decrement operators
54.Initialization
55.inline function specifier
56.integer constant
57.Lifetime
58.Logical operators
59.Lookup and name spaces
60.Main function
61.Member access operators
62.Memory model
63.Objects and alignment
64.Order of evaluation
65.Other operators
66.Phases of translation
67.Pointer declaration
68.Preprocessor
69.restrict type qualifier
70.return statement
71.Scalar initialization
72.Scope
73.sizeof operator
74.Statements
75.static assert declaration
76.Static storage duration
77.Storage-class specifiers
78.string literals
79.Struct and union initialization
80.Struct declaration
81.switch statement
82.Thread storage duration
83.Type
84.Type
85.Typedef declaration
86.Undefined behavior
87.Union declaration
88.Value categories
89.Variadic arguments
90.volatile type qualifier
91.while loop
92._Alignof operator
93._Noreturn function specifier
C

C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。