C语言标准库

来源:互联网 发布:职称计算机模拟软件 编辑:程序博客网 时间:2024/06/03 16:41

原文: http://gaomingfei.xyz/2016/04/18/C语言标准库总结/  作者: 高明飞

标准库(Standard Library)是C语言重要的一部分,不过学习C语言这么长时间,都没有细致的了解过标准库到底中包含哪些内容,这几天打算来仔细看看这部分内容。

C语言标准库有各种不同的实现,比如最著名的glibc, 用于嵌入式Linux的uClibc,还有ARM公司的自己的C语言标准库及精简版的MicroLib等。不同标准库的实现并不相同,而且提供的函数也不完全相同,不过有一个它们都支持的最小子集,这也就是最典型的C语言标准库。

这个C语言标准库中一共包含15个头文件,粗略的按常用程度排序列举如下:

Header FileContent<stdio.h>输入和输出<stdlib.h>最常用的一些系统函数<string.h>字符串处理<math.h>数学函数<ctype.h>字符类测试<time.h>时间和日期<stdarg.h>可变参数列表<signal.h>信号<assert.h>断言<setjmp.h>非局部跳转<errno.h>定义错误代码<stddef.h>一些常数、类型和变量<locale.h>本土化<float.h>浮点数运算<limits.h>定义整数数据类型的取值范围

在这里不准备列举所有库函数的详细用法,如需查询具体的库函数用法,可以参考以下几个链接:

Standard C 语言标准函数库速查 (Cheat Sheet)
C标准库参考手册
C Standard Library Reference Tutorial

本文总结的是不完整的C标准库,仅列举一些常用且最重要的部分。

关于C标准库本身的实现分析,可参考我的学习笔记:
C标准库学习笔记(1)——time、ctype、stdarg、assert

stdio.h

输入和输出。

在其中定义了以下一些常用的类型及常量:

NameCommentFILE文件指针EOFEnd Of File,表示文件的结尾stderr标准错误流stdin标准输入流stdout标准输出流

其中stderrstdinstdout为宏定义,是指向FILE类型的指针。

<stdio.h>中的函数有很多,大致可分为对标准输入输出流的操作、对文件流的操作、对标准错误流的操作、对字符串的操作这几大类。

标准输入输出流

其实从stdinstdout的定义中也可以看到,标准输入输出流也就是文件,只是一般情况下已经默认定义为键盘和屏幕。这与Linux中一切皆文件的思想一脉相承。

常用的函数有以下这些:

NameCommentint printf(const char * format, ...)格式化输出数据至stdoutint scanf(const char * format, ...)stdin读取格式化输入数据int putchar(int c)stdout输出一个字符int getchar(void)stdin读入一个字符int puts(const char * s)stdout输出一串字符串char * gets(char * s)stdin读入一串字符串

另外,vprintf()函数主要用于需要自己实现一些类似printf()的函数时使用,关于这个函数的用处可参考StackOverflow上的讨论,用于文件流的vfprintf()与用于字符串的vsprintf()的用处也是相似的。

文件流

对文件的操作是<stdio.h>中的核心,其他函数均可视为对特定文件的操作,大部分函数均以f****()命名。

最重要的函数是以下这几个:

NameCommentFILE * fopen(const char * filename, const char * mode)打开文件,失败返回NULLint fclose(FILE * stream)关闭文件,成功返回0,失败返回EOFsize_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream)读取文件内容size_t fwrite(cosnt void * ptr, size_t size, size_t nmemb, FILE * stream)写入文件内容

只使用这4个函数就可以完成基本的文件读写操作了,其它函数可以视为是为了更方便的进行文件读写而引入的。在Linux中,文件不仅仅是指磁盘上的一个file,也有可能是一个设备等,不过都可以以统一的方式进行读写。常用的打开模式有r(读)、w(写)、a(附加)、b(二进制)等。


与标准输入输出流的操作相同,对文件的操作也有以下这些函数:

NameCommentint fprintf(FILE * stream, const char * format, ...)格式化输出数据至文件int fscanf(FILE * stream, cosnt char * format, ...)由文件读取格式化输入数据int putc(int c, FILE * stream)向文件输出一个字符int getc(FILE * stream)由文件读入一个字符int fputc(int c, FILE * stream)向文件输出一个字符int fgetc(FILE * stream)由文件读入一个字符int fputs(const char * s, FILE * stream)向文件输出一串字符串(或比特流)char * fgets(char * s, int n, FILE * stream)由文件读入一串字符串(或比特流)

其中putc()fputc()getc()fgetc()的区别在于前者可能是使用宏定义实现的,而后者一定是函数,具体分析可以参考这篇文章。


用于对文件进行修改(如删除文件等)的函数有以下这些:

NameCommentint remove(const char * filename)删除文件,成功返回0int rename(const char * old, const char * new)更改文件名称或位置,成功返回0FILE * tmpfile(void)以wb+形式创建一个临时二进制文件

其中tmpfile()创建的临时文件在调用fclose()关闭时会被自动删除。


对文件流的定位通常使用以下这些函数:

NameCommentint fseek(FILE * stream, long int offset, int fromwhere)移动文件流的读写位置,错误返回非0long int ftell(FILE * stream)取得文件流的读取位置void rewind(FILE * stream)重设读取目录的位置为开头位置int feof(FILE * stream)检测文件结束符

whence可设置为SEEK_SETSEEK_ENDSEEK_CUR


使用这两个函数处理读写文件流操作中的错误:

NameCommentint ferror(FILE * stream)检查流是否有错误void clearerr(FILE * stream)复位错误标志

与缓冲(Buffer)机制有关的函数常用的有以下这两个:

NameCommentvoid setbuf(FILE * stream, char * buf)把缓冲区与流相联int fflush(FILE * stream)更新缓冲区,成功返回0,错误返回EOF

其他流操作

stderr的操作通过以下函数完成:

NameCommentvoid perror(const char * s)打印出错误原因信息字符串

此函数将上一个函数发生错误的原因输出到stderr,此错误原因依照全局变量errno的值来决定要输出的字符串,errno<errno.h>中声明。


对字符串也提供了格式化输入输出函数:

NameCommentint sprintf(char * s, const char * format, ...)格式化字符串复制int sscanf(const char * s, const char * format, ...)格式化字符串输入

stdlib.h

最常用的一些系统函数。

在其中定义了以下一些常用的类型及常量:

NameCommentsize_tsizeof运算符产生的数据类型,一般是一个无符号整数wchar_t一个宽字符的大小NULLRANDMAXrand()的最大返回值

下面分类整理一下其中的重要函数。

内存管理函数

最常用的是以下两个函数:

NameCommentvoid * malloc(size_t size)从堆上动态分配内存空间void free(void * ptr)释放之前分配的内存空间

还有一些常用的内存控制函数位于<string.h>中。

数学函数

常用函数有:

NameCommentint abs(int j)int类型数据绝对值long labs(long j)long类型数据绝对值int rand(void)产生一个随机数void srand(unsigned int seed)初始化随机数种子

关于rand()srand()的用法,之前写的这篇文章中进行了总结。

字符串转换函数

常用的有以下这3个函数:

NameCommentint atoi(const char * nptr)将字符串转换为整数(int)long atol(const char * nptr)将字符串转换为长整数(long)double atof(const char * nptr)将字符串转换为浮点型数(double)

环境函数

常用的函数有:

NameCommentint system(const char * string)执行Shell(或命令行)命令char * getenv(const char * name)获取环境变量中的内容int exit(int stauts)结束进程

搜索和排序函数

NameCommentvoid qsort(void * base, size_t nmemb, size_t size, int (* compar)(const void *, const void *))快速排序算法void * bsearch(const void * key, const void * base, size_t nmemb, size_t size, int (* compar)(const void *, const void *))在数组进行二分法查找某一元素,要求数组预先已排好序

<stdlib.h>中还有一些用于进行多字节字符处理的函数,此处没有列出。

string.h

<string.h>中除了字符串处理函数,还有一些内存管理函数:

NameCommentvoid * memset(void * dest, int c, size_t n)将一段内存空间填上某值void * memcpy(void * dest, const void * src, size_t n)复制一段内存内容int memcmp(const void * s1, const void * s2, size_t n)比较两段内存内容void * memchr(const void * s, int c, size_t n)在某一段内存范围中查找特定字节

常用的字符串操作函数有:

NameCommentchar * strcat(char * deat, const char * src)连接两个字符串char * strcpy(char * dest, const char * src)复制字符串int strcmp(const char * s1, const char * s2)比较两个字符串size_t strlen(const char * s)获取一个字符串的长度char * strtok(char * s1, const char * s2)分割字符串

以下这些函数用于进行字符串查找:

NameCommentchar * strchr(const char * s, int c)正向查找一个字符char * strrchr(const char * s, int c)反向查找一个字符char * strstr(const char * s1, const char * s2)查找一个字符串char * strpbrk(const char * s1, const char * s2)查找一个字符集合

math.h

标准数学库,常用函数如下:

三角函数

NameCommentdouble sin(double x)正弦double cos(double x)余弦double tan(double x)正切  double asin(double x)反正弦double acos(double x)反余弦double atan(double x)反正切double atan2(double y, double x)计算y/x的反正切

双曲三角函数

NameCommentdouble sinh(double x)双曲正弦double cosh(double x)双曲余弦double tanh(double x)双曲正切

指数与对数

NameCommentdouble exp(double x)e的n次幂double pow(double x, double y)x的y次幂double sqrt(double x)开根号  double log(double x)e为底的对数double log10(double x)10为底的对数

取整

NameCommentdouble ceil(double x)向上取整double floor(double x)向下取整

其它

NameCommentdouble fabs(double x)计算绝对值

ctype.h

包含字符测试及大小写转换函数。

字符测试

NameCommentisalpha(c)是否为字母isupper(c)是否为大写字母islower(c)是否为小写字母  isdigit(c)是否为数字isxdigit(c)是否为16进制数字(数字 & A~F & a~f)  isalnum(c)是否为字母及数字  ispunct(c)是否为标点符号isspace(c)是否为空白字符(空格、\r(CR)、\n(LF)、\t(TAB)、\v(VT)、\f(FF))iscntrl(c)是否为控制字符(ASCII 0 ~ 37(0x1F) & 177(0x7F))  isgraph(c)是否为可显示字符(字母 & 数字 & 标点)isprint(c)是否为可打印字符(字母 & 数字 & 标点 & 空白)

大小写转换

NameCommenttolower(c)转换为小写toupper(c)转换为大写

time.h

日期及时间操作。定义了time_tclock_ttm这几种类型,常用函数有:

获取时间及相关计算

NameCommenttime_t time(time_t * timer)获取UNIX时间戳,一般传入NULLclock_t clock(void)获取CPU时钟计数double difftime(time_t time1, time_t time0)计算时间差,time1 - time0  struct tm * gmtime(const time_t * timer)GMT时间struct tm * localtime(const time_t * timer)地方时时间time_t mktime(struct tm * timeptr)地方时时间

转换为可阅读的字符串

NameCommentchar * ctime(const time_t * timer)返回标准时间字符串,地方时时间,等价于asctime(localtime())char * asctime(const struct tm * timeptr)返回标准时间字符串size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *)返回自定义格式时间字符串

stdarg.h

用于支持可变参数,定义了va_list这个结构体,通过以下三个宏进行操作:

NameCommentvoid va_start(va_list ap, parmN)初始化va_listtype va_arg(va_list ap, type)va_list中获取一个type类型的参数void va_end(va_list ap)释放va_list

signal.h

定义了信号(Signal)处理的相关宏及函数,这与Linux中的信号机制密切相关,包含下面两个函数:

NameCommentsignal()设置处理特定Signal的Handlerraise(int sig)产生一个Signal

signal()函数原型如下:
void (* signal(int sig, void (* handler)(int)))(int);

assert.h

此头文件的唯一目的是提供assert(int x)这个宏,如果断言非真,程序会在标准错误流输出错误信息,并调用abort()函数使程序异常终止。

setjmp.h

非局部跳转,用于从一个深层次嵌套中直接返回至最外层,通过这两个宏完成:

NameCommentint setjmp(jmp_buf env)设置跳转点void longjmp(jmp_buf env, int val)进行跳转

errno.h

声明了一个外部整形变量errno用于表示错误,可用perror(const char * s)输出错误原因,其中s是错误提示前缀。

标准使用方法是:在一个库函数调用之前把它设为0,然后在下一个库函数调用前测试它,任何非零值均表示错误。示例代码:

1
2
3
4
5
6
7
8
#include <errno.h>
#include <math.h>

//......
errno = 0;
y = sqrt(x);
if (errno != 0)
perror("Error");

stddef.h

定义了一些标准定义,如size_twchar_tNULL等,这些定义也会出现在其他的头文件里。还定义了以下这个宏:

NameCommentoffsetof(type, member)返回结构体中某一成员相对于结构体起始地址的偏移量

locale.h

国家、文化和语言规则集称为区域设置,主要影响字符串格式,通过以下函数进行设置:

NameCommentsetlocale()设置或恢复本地化信息

float.h

用宏定义的方式定义了浮点数的最大值、最小值等信息。

limits.h

定义了基本数据类型(int、char、short等)的最大值及最小值。常用宏定义有:

NameCommentCHAR_BIT一个字节的比特数SCHAR_MIN带符号字符最小值SCHAR_MAX带符号字符最大值UCHAR_MAX无符号字符最大值CHAR_MINchar的最小值CHAR_MAXchar的最大值SHRT_MIN带符号短整型最小值SHRT_MAX带符号短整型最大值USHRT_MAX无符号短整型最大值INT_MIN带符号整形最小值INT_MAX带符号整形最大值UINT_MAX无符号整形最大值LONG_MIN带符号长整形最小值LONG_MAX带符号长整形最大值ULONG_MAX无符号长整形最大值

原创粉丝点击