C/C++标准库简介

缘起

【1】中我们讲了C的一些标准. 但是还是有点晕晕乎乎的——因为写完之后还是有疑惑——C标准到底规定了啥? 具体是啥? 【1】中只是讲了C标准规定了C编译器的行为. 但是具体规定了啥呢? 还有,我们一开始就疑惑的——我所使用的内核函数和类从何而来? 谁发明了它们? 他们是打包在我系统中的某个地方吗? 是否存在一份官方的C ++手册? 本文就继续来说透这些问题.

分析

C标准其实是ISO(早年1983是ANSI,美国国家信息标准化协会),即大名鼎鼎的国际标准化组织一大群人聚会来讨论和定义语言规则,最终都会得到一本官方的叫《标准》的书,你可以从他们的网站中购买。 这些标准就是我们所谓的C99、C11、C++03、C++11、C++14.

这些书一般分成两部分.

  1. C/C++的功能和特性

    大家看一张图,感受一下

    这是C标准库第一部分的摘选,它定义main函数的结构.

  2. C/C++ API, 其实就是一大堆的头文件.

    大家也看一张图,感受感受

    这是在math.h头文件中定义min函数.

所以说C/C++标准就是由上述两部分构成,换言之,C/C++标准定义的就是这些东西. 也就是所谓形而上学的东西——并没有给出任何实现(再换言之,只是给出标准,或者说规范,再或者说接口,而没有任何落地实现).

而所谓C/C++标准库是什么呢? 它和C/C++标准是什么关系呢? 它们其实在C/C++标准中定义. 可以粗略理解为第二部分——或者说一大堆的头文件. 确切讲是

1
2
3
4
5
6
7
8
9
C标准库
C标准库也称为ISO C库,是用于完成诸如输入/输出处理、字符串处理、内存管理、数学计算和许多其他
操作系统服务等任务的宏、类型和函数的集合。它是在C标准中(例如C11标准)中定义的。其内容分布在
不同的头文件中,比如上面我所提到的math.h。

C++标准库
和C标准库的概念类似,但仅针对C ++。C++标准库是一组C++模板类,它提供了通用的编程数据结构和
函数,如链表、堆、数组、算法、迭代器和任何其他你可以想到的C++组件。C ++标准库也包含了C标准
库,并在C++标准中进行了定义(例如C++ 11标准)。

那么既然接口给出来了,实现总得给吧~ 事情不落地总归是不行的.

也就是说必须有人阅读这些《标准》并将其转换成计算机可以读懂的东西。这是工作于编译器上的工程师所做的事情, 其中编译器是一种可以读取和处理C/C++源文件的工具.

关于C/C++标准库的实现是由从事标准库实现的开发者完成的. 他们必须要依赖具体机器硬件提供的功能(读/写文件,分配内存,创建线程,……所有这些统统被称为系统调用(system call)),C标准库使用C实现之后,经过具体硬件机器上的C编译器编译成动态库(.dll或者linux平台下的.so文件)(汇编)或者静态库(.lib),这些编译好的东西里面全都是系统调用. 所以不难知道每个具体的硬件平台都有其自己的C/C++标准库实现。 有时它是系统内核的一部分,有时它是作为一个附加组件 - 编译器 - 必须单独下载。

GNU/Linux 版的实现就是著名的 glibc(C标准库的GNU项目实现),但是并非所有的标准C函数都可以在glibc中找到:大多数数学函数实际上是在libm库中实现的,这是一个独立的库.

截至今天,glibc是Linux上使用最广泛的C库。 然而,在90年代期间,有一段时间里,glibc有一个竞争对手称为Linux libc(或者简称libc),它是由glibc 1.x的一个分支产生的。在一段时间里,Linux libc是许多Linux发行版中的标准C库。经过多年的发展,glibc竟然比Linux libc更具优势,并且所有使用libc的Linux发行版都切换回了glibc。 但是磁盘却只能找到一个名为libc.so.6的文件——请不要担心:它就是glibc。为了避免与之前的Linux libc版本混淆,版本号增加到了6(无法将其命名为glibc.so.6,因为所有Linux库都必须以lib前缀打头)。

Windows平台上,标准库的实现一直严格限定在Visual Studio中,它是微软官方的编译器。他们通常称之为C/C++运行时库(CRT),并且它涵盖了c/c++二者的实现。

其实标准库也就是我们在vs2010中看到的那个include路径中的东西. 而标准库的实现也就是我们在vs2010中看到的那个lib路径中的东西. 右键项目点击Properties之后见下图

脱离标准库

不使用标准库很简单:只要在你的程序中不引入它们的任何一个头文件,你的目标就达成了。但是为了让这种目标更有意义一些,我们自己需要通过既存的系统调用来与硬件设备交互. 这样做很可能会使得我们编写的程序丧失可移植性. 但是在某些应用场景下源代码不需要可移植性,在有限的内存中每个字节都很重要,我们必须更加精准地编写代码!在那里不允许使用标准库!

参考

【1】https://yfsyfs.github.io/2019/07/15/ANSI-C-C89-C90-C99-C11/

【2】https://www.cnblogs.com/findumars/p/9000371.html