C 语言的标准库通常包含了一组标准头文件和一个或几个库函数代码文件。在写 C 程序时,只需使用 #include 预处理命令引入相关头文件,就可以保证程序里能够正确使用标准库功能了。
在这些头文件里列出了各个库函数的原型,定义了库函数所使用的有关类型(如表示流的 FILE 结构类型等)和一些符号常量(如 EOF、NULL)。
标准头文件包括:
C标准头文件
下面是对每个标准库所包含的函数功能的简单介绍。
1、<stdio.h>
stdio.h 即 standard input & output(标准输入输出)。在源代码中如用到标准输入输出函数时,就要包含这个头文件。
stdio.h所包含的函数:
- 文件访问:fopen、freopen、fflush、fclose
- 二进制输入/输出:fread、fwrite
- 非格式化输入/输出:fgetc/getc、fputc/putc、ungetc、fgets、fputs
- 格式化输入/输出:scanf/fscanf/sscanf、printf/fprintf/sprintf、perror
- 文件定位:ftell、fseek、fgetpos、fsetpos、rewind
- 错误处理:feof、ferror
- 文件操作:remove、rename、tmpfile
2、<stdlib.h>
stdlib.h 即 standard library 标准库头文件。stdlib.h里面定义了五种类型、一些宏和常用的系统函数。
- 类型:size_t、wchar_t、div_t、ldiv_t和lldiv_t;
- 宏例:EXIT_FAILURE、EXIT_SUCCESS、RAND_MAX和MB_CUR_MAX等;
常用的函数:malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、srand()、exit()等。
- int atoi(const char *nptr):表示 ascii to integer,把字符串转换成整型数;
- long atol(const char *nptr):把字符串转换成长整型数;
- rand():产生随机数的一个随机函数;
- void srand(unsigned int seed):srand和rand()配合使用产生伪随机数序列。
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。srand通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列
3、<stddef.h>
stddef.h 定义了一些标准宏和类型,包括:
- size_t(sizeof运算符的结果类型,无符号整型);
- ptrdiff_t (两个指针相减运算的结果类型,有符号整型);
- wchar_t (宽字符类型,整型);
- 指针常量 NULL(空指针值);
- offsetof(type, member-designator) :获得字段在结构体中的偏移量。
无论包含哪个标准头文件,都会自动将<stddef.h>包含进来。
4、<ctype.h>
ctype.h 定义了一批C语言字符分类函数(C character classification functions),用于测试字符是否属于特定的字符类别,如字母字符、控制字符等。
- int isalpha(char ch):检查ch是否是字母;
- int iscntrl(int ch):检查ch是否控制字符(其ASCII码在0和0x1F之间,数值为 0-31);
- int isdigit(char ch):检查ch是否是数字(0-9);
- int islower(int ch):检查ch是否小写字母(a-z);
- int isupper(int ch):检查ch是否是大写字母(A-Z);
- int tolower(int ch):将ch字符转换为小写字母;
- int toupper(int ch):将ch字符转换成大写字母;
- int isspace(int ch):检查ch是否是空格符、跳格符或换行符;
- int isascii(int ch):测试参数是否是ASCII码0-127;
5、<string.h>
关于字符数组的函数定义的头文件,常用函数有strlen、strcmp、strcpy等。
- char *strcpy(char *destin, char *source):拷贝一个字符串到另一个;
- char *strncpy(char *dest, char *src, size_t n):将字符串src中最多n个字符复制到字符数组dest中,它并不像strcpy一样遇到NULL才停止复制,而是等凑够n个字符才开始复制;
- char *strcat(char *destin, char *source):字符串拼接函数;
- char *strrev(char *str):字符串倒转;
- char *strchr(char *str, char c):在一个串中查找给定字符的第一个匹配之处;
- size_tstrlen(const char *s):求字符串的长度,从字符串的首地址开始到遇到第一个'\0'停止计数;
- int strcmp(char *str1, char *str2):字符串比较,看ASCII 码,str1>str2,返回值 > 0;两串相等,返回0;
6、<limits.h>
limits.h 文件里的宏限制了各种变量类型(比如 char、int 和 long)的值。
在不同的平台、不同的编译器下,整型数据的取值范围可能会有所不同,用户可以读取该头文件中的宏来了解当前环境下整型数据的取值范围。
7、<float.h>
float.h 文件里包含了一组与浮点值相关的依赖于平台的常量。
下面的值是特定实现的,且是通过 #define 指令来定义的。其中,FLT 是指类型 float,DBL 是指类型 double,LDBL 是指类型 long double。
8、<math.h>
<math.h> 文件包含了各种数学函数。
主要有三角函数、幂函数(exp())、对数函数(log())、取绝对值函数(fabs())、取整函数(ceil(), floor(), round())等。
9、<time.h>
time.h 头文件定义了四个变量类型、两个宏和各种操作日期和时间的函数。
定义的变量类型:
- size_t:无符号整数类型,是 sizeof 计算的结果;
- clock_t :存储处理器时间的类型;
- time_t:存储日历时间类型;
- struct tm:用来保存时间和日期的结构。
定义的宏:
- NULL:这个宏是一个空指针常量的值;
- CLOCKS_PER_SEC:这个宏表示每秒的处理器时钟个数。
定义的函数:
- clock_t clock(void):返回程序执行起(一般为程序的开头),处理器时钟所使用的时间。
- time_t time(time_t *timer):计算当前日历时间,并把它编码成 time_t 格式。
- char *ctime(const time_t *timer):返回一个表示当地时间的字符串,当地时间是基于参数 timer。
- double difftime(time_t time1, time_t time2):返回 time1 和 time2 之间相差的秒数 (time1-time2)。
- time_t mktime(struct tm *timeptr):把 timeptr 所指向的结构转换为一个依据本地时区的 time_t 值。
- struct tm *localtime(const time_t *timer):timer 的值被分解为 tm 结构,并用本地时区表示。
10、<errno.h>
<errno.h> 文件里定义了 errno,是一个int型的值。 errno 可以看作一个变量,其初始值为 0,任何标准库函数执行中出错都可能将它设置为非 0 值,但任何标准库函数的执行都不会出现将它设置为 0 的动作。
在<errno.h>里还定义了两个宏 EDOM 和 ERANGE,它们都是非 0 整数值。如果数学函数执行中遇到参数错误(参数超出了函数的允许范围),就会将 errno 设置为 EDOM。如果数学函数计算中出现值域错误(结果溢出),就会将 errno 设置为 ERANGE。
此外,标准库还允许具体系统定义一些以 E 开头的宏,用于表示具体 C 系统的标准库可能给 errno 设置的值。
11、<setjmp.h>
setjmp.h 文件定义了宏 setjmp()、函数 longjmp() 和变量类型 jmp_buf,该变量类型会绕过正常的函数调用和返回规则。
- jmp_buf:用于存储宏 setjmp() 和函数 longjmp() 相关信息的数组类型。
- int setjmp(jmp_buf environment):这个宏把当前环境保存在变量 environment 中,以便函数 longjmp() 后续使用。如果这个宏直接从宏调用中返回,则它会返回零,但是如果它从 longjmp() 函数调用中返回,则它会返回一个非零值。
- void longjmp(jmp_buf environment, int value):该函数恢复最近一次调用 setjmp() 宏时保存的环境,jmp_buf 参数的设置是由之前调用 setjmp() 生成的。
12、<signal.h>
signal.h 文件定义了一个变量类型 sig_atomic_t、两个函数调用和一些宏来处理程序执行期间报告的不同信号。
- sig_atomic_t:int 类型,在信号处理程序中作为变量使用。它是一个对象的整数类型,该对象可以作为一个原子实体访问,即使存在异步信号时,该对象可以作为一个原子实体访问。
下面是头文件 signal.h 中定义的宏:
- SIG_DFL:默认的信号处理程序;
- SIG_ERR:表示一个信号错误;
- SIG_IGN:忽视信号。
- signal.h 中定义的函数:
定义的函数:
- void (*signal(int sig, void (*func)(int)))(int):该函数设置一个函数来处理信号,即信号处理程序。
- int raise(int sig):该函数会促使生成信号 sig。sig 参数与 SIG 宏兼容。
13、<assert.h>
assert.h 文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息。
assert 宏的定义如下:
- #define assert(ignore) ((void)0)
assert.h 中定义的唯一的函数:
- void assert(int expression):这实际上是一个宏,不是一个函数,可用于在 C 程序中添加诊断。
14、<locale.h>
locale.h 文件定义了特定地域的设置,比如日期格式和货币符号。
15、<stdarg.h>
stdarg.h 文件定义了一个变量类型 va_list 和三个宏,这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数。
可变参数的函数通在参数列表的末尾是使用省略号(,...)定义的。
定义的变量类型:
- va_list:适用于 va_start()、va_arg() 和 va_end() 这三个宏存储信息的类型。
定义的宏:
- void va_start(va_list ap, last_arg):这个宏初始化 ap 变量,它与 va_arg 和 va_end 宏是一起使用的。last_arg 是最后一个传递给函数的已知的固定参数,即省略号之前的参数。
- type va_arg(va_list ap, type):这个宏检索函数参数列表中类型为 type 的下一个参数。
- void va_end(va_list ap):这个宏允许使用了 va_start 宏的带有可变参数的函数返回。如果在从函数返回之前没有调用 va_end,则结果为未定义。