C语言的标准库总共分成十五个部分,每个部分用一个头描述。许多编译器都会使用扩展后的库,因此,包含的头通常会多于十五个。额外添加的头当然不属于标准库的范畴,所以,我们
- C语言的标准库总共分成十五个部分,每个部分用一个头描述。许多编译器都会使用扩展后的库,因此,包含的头通常会多于十五个。额外添加的头当然不属于标准库的范畴,所以,我们不能假设其他的编译器也可以支持这些头。而这些头通常提供一些针对特定机型或特定操作系统的函数,他们可能会提供对屏幕或键盘更多的操作函数,用于支持图形或窗口界面。
- 标准头主要由函数原型、类型定义以及宏定义组成。如果我们的文件中调用了头中的函数,或是使用了头中定义的类型或宏,那么我们就需要在文件开头将相应的头包含进来,当一个文件包含了多个头时,这些头的顺序无关紧要。
标准库中使用名字的一些限制
- 任何包含了标准头的文件都必须遵守两条规则:第一该文件不能以任何目的使用在头文件中已经定义过的宏的名字。第二,具有文件作用域的库名尤其是类型名,也不可以在文件中再次使用。
- 虽然上述这些限制似乎是显而易见的,但c语言还有一些其他的限制可能是你想不到的:
使用宏隐藏函数
- c程序员经常会用宏来替代小的函数,这在标准库中同样很常见。C语言标准允许在头中定义与库函数同名的宏。为了起到保护作用,还要求有实际的函数存在。因此对于库的头,声明一个函数并同时定义一个有相同名字的宏的情况并不少见。
在<ctype.h>中有大量这样成对的函数和宏定义的例子。
- 例如,用来检测一个其字符是否可以显示的函数isprint。通常的做法是在<ctype.h>中定义 isprint作为一个函数:
并同时把他定义为一个宏:
#define isprint( c ) ((c >= 0x20 && (c) <= 0x7e )- 在默认情况下,对isprint的调用会被作为宏调用,因为宏名会在预处理时被替换。那么问题来了,如果在某些情况下,我们需要调用的是一个真实的函数,那又该如何调用同名函数呢? 这里有两种方式可供大家选择:
#undef isprint
预处理器无法分辨出带圆括号的宏,而编译器不会这么容易被欺骗,他任然可以认出isprint函数。