跳转至

第二十一章 标准库


标准库的使用

C89标准库有15个部分,即15个头文件。

标准头主要由函数原型、类型定义和宏定义组成。

<assert.h> 诊断

允许程序插入自我检查,一旦检查失败,程序就被终止。

<ctype.h> 字符处理

提供用于字符分类及大小写转换的函数。

<errno.h> 错误

提供了error number,它是一个左值,可以在调用特定库函数后进行检测,来判断调用过程中是否有错误发生。

<float.h> 浮点类型的特性

提供了用于描述浮点类型特定的宏,包括值的范围及精度。

<limits.h> 整数类型的大小

提供了用于描述整数类型特性的宏,包括他们的最大值和最小值。

<locale.h> 本地化

提供一些函数来帮助程序适应针对某个国家或地区的特定行为方式。包括显示数的方式、货币的格式、字符集以及日期和时间的表示形式。

<math.h> 数学计算

提供常见的数学函数。

<setjmp.h> 非本地跳转

提供了setjmp和longjmp函数,setjmp会标记程序中的一个位置,随后可以用longjmp返回标记的位置。可以实现从一个函数跳转到另一个函数中,绕过正常的函数返回机制。主要用来处理程序中的严重问题。

<signal.h> 信号处理

提供了用于处理异常的函数,包括中断和运行时错误。signal可以设置一个函数,使系统信号到达时自动调用该函数;raise函数用来产生信号。

<stdarg.h> 可变参数

提供一些工具用于编写参数个数可变的函数。

<stddef.h> 常用定义

提供经常使用的类型和宏定义。

<stdio.h> 输入与输出

提供大量的输入和输出函数,包括对文件的顺序访问和随机访问操作。

<stdlib.h> 常用实用程序

包含大量无法划归其它头的函数。包含函数:将字符串转换成数,产生伪随机数,执行内存管理任务,与操作系统通信,执行搜索与排序等。

<string.h> 字符串处理

包含操作字符串的函数。

<time.h> 日期和时间

提供相应的函数来获取时间,操纵时间,以及格式化时间。

对标准库中所用名字的限制

只要包含了标准头(没有不包含的情况吧?),必须遵循两条规则:

  1. 不用自己定义标准头已定义过的宏

  2. 具有文件作用域的库名也不可以在文件层次重定义

还有一些命名规则,不要与标准库有冲突:

  • 由一个下划线和一个大写字母开头,或由两个下划线开头的标识符,是标准库保留的标识符

  • 由一个下划线开头的标识符,被保留用作具有文件作用域的标识符和标记,只可用于函数内部声明

  • 在标准库中所有具有外部链接的标识符被保留用作具有外部链接的标识符,比如printf

使用宏隐藏的函数

C语言允许在头中定义与库函数同名的宏。从而使得宏隐藏掉函数。

使用宏可能会提高程序的运行速度。如果有不想使用宏的情况,可能是因为想缩小可执行代码的大小。

若要删掉宏,可用如下方法:

#include <stdio.h>
#undef getchar

还可以禁用宏:

(getchar)()

stddef.h 常用定义

此头提供了常用的类型和宏的定义。定义的类型包括以下几个:

  • ptrdiff_t,指针相减的结果类型,是有符号整数

  • size_t,sizeof运算符返回的类型,是无符号整数

  • wchar_t,一种足够大的,可以用来表示所有支持的地区的所有字符的类型

其中一个宏是:offsetof,其意思是求得结构体的起点到指定成员间的字节数。

比如,有下面的结构体:

struct s {
    char a;
    int b[2];
    float c;
};

offsetof(struct s, a)的值一定是0,因为结构体的首元素的地址一定是结构体的地址;

offsetof(struct s, b)的值可能是1,但也可能是4(考虑到字节对齐)。