本教程视频已同步到B站: 程序员的C——实用编程,不玩虚的!
标准库的学习
标准库
维基百科
C标准库或libc是ANSI C标准中规定的C编程语言的标准库,它与C库POSIX规范是同时制定的,POSIX规范是它的超集,由于ANSI C被国际标准化组织采用,C标准库也被称为ISO C库。
C标准库为字符串处理、数学计算、输入/输出处理、内存管理等任务以及其他一些操作系统服务提供了宏、类型定义和函数。
什么是CRT?
CRT是指C运行时库(C run-time library) 。最早的时候,C 语言被开发出来时,Dennis Ritchie 和 Brian Kernighan 就用 C 语言重写了 90% 以上的 UNIX 系统函数,并且把其中最常用的部分独立出来,形成头文件和对应的 library,C run-time library 就是这样形成的。
随着 C 语言的流行,各个 C 编译器的生产商/个体/团体都遵循老的传统,在不同平台上都有相对应的 Standard Library,但大部分实现都是与各个平台有关的。由于各个 C 编译器对 C 的支持和理解有很多分歧和微妙的差别,所以就有了 ANSI C;ANSI C (主观意图上)详细的规定了 C 语言各个要素的具体含义和编译器实现要求,引进了新的函数声明方式,同时订立了 Standard Library 的标准形式。所以C运行时库由编译器生产商提供。至于由其他厂商/个人/团体提供的头文件和库函数,应当称为第三方 C 运行库(Third party C run-time libraries)。
如果没有CRT,main()
就不会被调用,exit()
也不能被响应。因为CRT包含了C程序运行的最基本和最常用的函数。
不同的编译器有不同的CRT,微软的编译器是MSVC,其CRT全名为Microsoft Visual C++ C Runtime,是Windows下的C运行时库。GCC提供的CRT则是glibc,全名为GNU C Library,作为Linux下的C运行时库。glibc 官方地址
要想更多了解其CRT详细信息及MSVC相关用法,可查看 MSVC 官方中文文档 进行学习,也可以直接查看其标准库实现源码,在安装了最新的VS2019
的机器上,我的CRT源码路径为D:\Windows Kits\10\Source\10.0.18362.0\ucrt
,大家可以据此找到自己的源码路径。而对于glibc,则可以去上述官网下载源码学习,或者查看其glibc 官方手册学习函数
作为一个主要关注移动设备的开发者,我们可能对Android的CRT更感兴趣。实际上谷歌并没有使用内容比较杂乱的glibc,而是专门为Android设备重新开发了一套全新的CRT,它就是bionic,其源码位于Android系统的主体源码仓库中,不过有人单独检出了源码并放到了GitHub上,可用于学习。bionic 地址
另外,这里再给出一个中文版C语言标准文档,既可以查询C语言的标准语法,也可查看库函数用法。
标准库头文件
C89标准共划分成15个头文件,C99新增了9个,总共有24个:
头文件 | 描述 |
---|---|
<assert.h> |
仅包含assert宏,它允许我们在程序中插入自我检查 |
<ctype.h> |
提供用于字符分类及大小写转换的函数 |
<errno.h> |
提供了errno 。errno 是一个左值,可以在调用特定库函数后进行检测,来判断调用过程中是否有错误发生 |
<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> |
提供相应的函数来获取时间(和日期),操纵时间,以及格式化时间的显示 |
C99新增头:
头文件 | 描述 |
---|---|
<complex.h> |
提供了对复数进行数学运算的函数 |
<fenv.h> |
提供了对浮点状态标志和控制模式的访问。例如,程序可以测试标志来判断浮点数运算过程中是否发生了溢出,或者设置控制模式来指定如何进行取整 |
<inttypes.h> |
定义了可用于<stdint.h> 中声明的整数类型的输入/输出的格式化字符串的宏,还提供了处理最大宽度整数的函数 |
<iso646.h> |
定义了可代表特定运算符(包含字符& 、|、~ 、! 和^ 的运算符)的宏。当编程环境的本地字符集没有这些字符时,这些宏非常有用 |
<stdbool.h> |
定义了bool、true和false宏,同时还定义了一个可以用于测试这些宏是否已被定义的宏 |
<stdint.h> |
声明了指定宽度的整数类型并定义了相关的宏(例如指定每种类型的最大和最小值的宏)。同时定义了用于构建具体类型的整数常量的带参数的宏 |
<tgmath.h> |
该头中的泛型宏可以检测传递给它们的参数的类型,并替代为相应<math.h> 或<complex.h> 中函数的调用 |
<wchar.h> |
提供了宽字符输入/输出和宽字符串操作的函数 |
<wctype.h> |
是<ctype.h> 的宽字符版本,提供了对宽字符进行分类和修改的函数 |
其他CRT实现
- FreeBSD libc
- NetBSD libc
- OpenBSD libc
- uClibc 它是用于开发嵌入式Linux系统的小型C库。它比GNU C库小得多,但是glibc支持的几乎所有应用程序也可以与uClibc完美配合
- Dietlibc 专为最小的二进制文件设计的C标准库
C POSIX库
C POSIX库是一个针对POSIX系统的C标准库的规范。它是与ANSI C标准同时开发的。为了使POSIX与标准C兼容,做了一些努力;POSIX包括标准C中引入的附加功能。
C POSIX库头的文件
头文件 | 描述 | 首次发布 |
---|---|---|
<aio.h> |
异步输入输出 | 第5期 |
<arpa/inet.h> |
操纵数字IP地址的功能(Berkeley套接字的一部分) | 第6期 |
<assert.h> |
验证假设 | 第1期 |
<complex.h> |
复杂算术,请参阅C数学函数 | 第6期 |
<cpio.h> |
cpio归档格式的魔数 | 第3期 |
<ctype.h> |
字符类型 | 第1期 |
<dirent.h> |
允许打开和列出目录 | 第2期 |
<dlfcn.h> |
动态链接 | 第5期 |
<errno.h> |
检索错误号 | 第1期 |
<fcntl.h> |
文件打开,锁定和其他操作 | 第1期 |
<fenv.h> |
浮点环境(FPE),请参阅C数学函数 | 第6期 |
<float.h> |
浮点类型,请参阅C数据类型 | 第4期 |
<fmtmsg.h> |
消息显示结构 | 第4期 |
<fnmatch.h> |
文件名匹配 | 第4期 |
<ftw.h> |
文件树遍历 | 第1期 |
<glob.h> |
路径名“ globbing”(模式匹配) | 第4期 |
<grp.h> |
用户组信息和控制 | 第1期 |
<iconv.h> |
代码集转换工具 | 第4期 |
<inttypes.h> |
固定大小的整数类型,请参阅C数据类型 | 第5期 |
<iso646.h> |
备用拼法,见C备用标记 | 第5期 |
<langinfo.h> |
语言信息常量–基于C本地化功能 | 第2期 |
<libgen.h> |
路径名操作 | 第4期 |
<limits.h> |
实现定义的常量,参见C数据类型。 | 第1期 |
<locale.h> |
类别宏,请参见C本地化功能 | 第3期 |
<math.h> |
数学声明,请参阅C数学函数 | 第1期 |
<monetary.h> |
货币单位的字符串格式 | 第4期 |
<mqueue.h> |
消息队列 | 第5期 |
<ndbm.h> |
NDBM数据库操作 | 第4期 |
<net/if.h> |
本地网络接口列表 | 第6期 |
<netdb.h> |
将协议和主机名转换为数字地址(Berkeley套接字的一部分) | 第6期 |
<netinet/in.h> |
定义Internet协议和地址族(Berkeley套接字的一部分) | 第6期 |
<netinet/tcp.h> |
其他TCP控制选项(伯克利套接字的一部分) | 第6期 |
<nl_types.h> |
本地化消息目录功能 | 第2期 |
<poll.h> |
异步文件描述符多路复用 | 第4期 |
<pthread.h> |
定义用于创建和操作POSIX线程的API | 第5期 |
<pwd.h> |
passwd(用户信息)访问和控制 | 第1期 |
<regex.h> |
正则表达式匹配 | 第4期 |
<sched.h> |
执行调度 | 第5期 |
<search.h> |
搜索表 | 第1期 |
<semaphore.h> |
POSIX 信号量 | 第5期 |
<setjmp.h> |
堆栈环境声明 | 第1期 |
<signal.h> |
信号,请参阅C信号处理 | 第1期 |
<spawn.h> |
处理Spawn | 第6期 |
<stdarg.h> |
处理变量参数列表 | 第4期 |
<stdbool.h> |
布尔类型和值,请参阅C数据类型 | 第6期 |
<stddef.h> |
标准类型定义,请参阅C数据类型 | 第4期 |
<stdint.h> |
整数类型,请参阅C数据类型 | 第6期 |
<stdio.h> |
标准缓冲的输入/输出,请参见C文件输入/输出 | 第1期 |
<stdlib.h> |
标准库定义,请参见C标准库 | 第3期 |
<string.h> |
几个字符串操作,请参阅C字符串处理 | 第1期 |
<strings.h> |
不区分大小写的字符串比较 | 第4期 |
<stropts.h> |
流操作,包括ioctl | 第4期 |
<sys/ipc.h> |
进程间通信(IPC) | 第2期 |
<sys/mman.h> |
内存管理,包括POSIX 共享内存和内存映射文件 | 第4期 |
<sys/msg.h> |
POSIX 消息队列 | 第2期 |
<sys/resource.h> |
资源使用,优先级和限制 | 第4期 |
<sys/select.h> |
同步I/O复用 | 第6期 |
<sys/sem.h> |
XSI(SysV式)信号灯 | 第2期 |
<sys/shm.h> |
XSI(SysV样式)共享内存 | 第2期 |
<sys/socket.h> |
主要的Berkeley套接字头文件 | 第6期 |
<sys/stat.h> |
文件信息(stat等) | 第1期 |
<sys/statvfs.h> |
文件系统信息 | 第4期 |
<sys/time.h> |
时间和日期的功能和结构 | 第4期 |
<sys/times.h> |
文件访问和修改时间 | 第1期 |
<sys/types.h> |
其他地方使用的各种数据类型 | 第1期 |
<sys/uio.h> |
向量化I/O操作 | 第4期 |
<sys/un.h> |
Unix域套接字 | 第6期 |
<sys/utsname.h> |
操作系统信息,包括uname | 第1期 |
<sys/wait.h> |
终止子进程的状态(请参阅wait) | 第3期 |
<syslog.h> |
系统错误记录 | 第4期 |
<tar.h> |
"tar "文档格式的魔数。 | 第3期 |
<termios.h> |
允许终端I/O接口 | 第3期 |
<tgmath.h> |
类型通用宏,请参见C数学函数 | 第1期 |
<time.h> |
类型通用宏,请参见C日期和时间函数 | 第1期 |
<trace.h> |
跟踪运行时行为(不建议使用) | 第6期 |
<ulimit.h> |
资源限制(建议使用<sys/resource.h> ) |
第1期 |
<unistd.h> |
各种基本的POSIX函数和常量 | 第1期 |
<utime.h> |
索引节点访问和修改时间 | 第3期 |
<utmpx.h> |
用户计费数据库功能 | 第4期 |
<wchar.h> |
宽字符处理,请参阅C字符串处理 | 第4期 |
<wctype.h> |
宽字符分类和映射实用程序,请参见C字符分类 | 第5期 |
<wordexp.h> |
像shell那样进行文字扩展 | 第4期 |
关于POSIX库详细信息及头文件描述,请查阅Open Group基本规范文档
第三方库
-
APR
由 Apache 社区维护的 C 开源库,主要提供操作系统相关的功能(文件系统、进程、线程、用户、IPC)。此外还提供了一些网络相关的功能。原先是 Apache Web 服务器的一个组成部分,后来独立出来,成为一个单独的开源项目。 -
libVLC
开源 (VLC SDK)媒体框架,著名的支持各种媒体格式的VLC播放器的核心 -
SDL
是一个跨平台的开发库,旨在通过 OpenGL 和 Direct3D 为音频、键盘、鼠标、操纵杆和图形硬件提供低级访问 -
TCC
TCC(Tiny C Compiler)是一个快速的轻量级的C语言编译器 -
http-parser
用C编写的HTTP消息解析器。它解析请求和响应。 该解析器旨在用于高性能的HTTP应用中。 它不进行任何系统调用或分配,也不缓冲数据,可以随时中断。 根据你的架构,每个消息流(在每个连接的Web服务器中)仅需要大约40字节的数据。
全面的C语言的第三方库介绍,查看 awesome-c
关注公众号:编程之路从0到1