本文将介绍在编写C/C++应用程序的领域中,标准库的作用以及它是如何在各个操作系统中实现的。

我一直在玩 C++,一开始总是让我感到困惑的一件事是C++程序的构成:我使用的核心函数和类来自哪里?是谁发明了它们?它们是否打包在我系统的某个地方?有没有一种官方的 C++ 手册

在本文中,我将尝试回答这些问题,从 C 和 C++ 语言的本质到它们的实际实现。

C 和 C++ 是如何产生的

当我们谈论 C 和 C++ 时,我们实际上说的是一系列规则,这些规则定义了编程语言应该做什么、它们应该如何表现以及它们应该提供什么功能。一个C/C++ 编译器必须遵循这些规则才能处理用 C/C++ 编写的源代码并生成二进制应用程序。这听起来非常接近 HTML:浏览器遵循的一组指令,以便它们可以以明确的方式呈现网页。

与 HTML 一样,C 和 C++ 规则是理论上的。国际标准化组织 (ISO)的一大群人每年数次聚集在一起,讨论并在纸上定义编程语言规则。是的,C 和 C++ 是标准化的东西。他们最终得到了一本名为标准的官方书籍,你可以从他们的网站上购买。随着语言的发展,新论文不断发布,每次都定义一个新标准。这就是为什么我们有不同的 C 和 C++ 版本:C99、C11、C++03、C++11、C++14 等等,其中的数字与出版年份一致。

这些标准是非常详细的技术文件:我不会将它们用作手册。它们通常分为两部分:

  1. C/C++ 特性和功能;
  2. C/C++ API — 开发人员在其 C/C++ 程序中使用的类、函数和宏的集合。它被称为标准库

例如,这里是从C 标准main的第一部分中选择的,其中定义了函数的构成:

下面是描述 C API标准库中的fmin函数的描述:

正如你看见的,标准的文档中几乎不涉及任何代码。必须有人阅读标准并将其转换为计算机可以理解的东西。这就是从事编译器和实现工作的人们所做的:前者制作了一个可以读取和处理 C 和 C++ 源文件的工具(即编译器),后者将标准库转换为代码(比如将标准库中关于函数功能的约定通过代码实现出来,标准只是规定了,但是没有代码,需要写出符合标准的代码)。让我们更深入地研究一下。

C 标准库

C 标准库,也称为ISO C 库,是一系列的宏、类型和函数的集合,它们用于输入/输出处理、字符串处理、内存管理、数学计算和许多其他操作系统服务等任务。它在 C 标准(例如 C11 标准)中指定。内容分布在不同的头文件中,就像上面提到的math.h

C++ 标准库

就像 C 有标准库一样, C++也有它的标准库。C++ 标准库是一组 C++ 模板类,它提供常见的编程数据结构和函数,例如列表、堆栈、数组、算法、迭代器和你能想到的任何其他 C++ 组件。C++ 标准库也包含 C 标准库,并且在 C++ 标准(例如 C++11 标准)中指定。

实现 C 和 C++ 标准库

我们从这里开始讨论真正的代码。从事标准库实现工作的开发人员阅读官方 ISO 要求并将其转换为代码。他们必须依赖操作系统提供的功能(读/写文件、分配内存、创建线程……,通过所谓的系统调用),所以每个平台都有自己的标准库实现。有时它是系统的核心部分,有时它作为附加组件——编译器(必须单独下载)。

GNU/Linux 实现

GNU C 库,也称为glibc,是 GNU 项目对 C 标准库的实现。并非所有标准 C 函数都可以在 glibc 中找到:大多数数学函数实际上是在libm中实现的,这是一个单独的库。

到目前为止,glibc 是 Linux 上使用最广泛的 C 库。然而,在 90 年代,有一段时间有一个 glibc 的竞争对手,称为Linux libc(或简称为libc),它诞生于 glibc 1.x 的一个分支。有一段时间,Linux libc 是许多 Linux 发行版中的标准 C 库。

经过多年的发展,glibc 被证明比 Linux libc 优越得多,并且所有使用它的 Linux 发行版都切换回了 glibc。因此,如果你在磁盘中找到一个名为的libc.so.6文件,请不要担心:它是现代 glibc。版本号增加到 6 以避免与以前的 Linux libc 版本混淆(他们无法命名glibc.so.6:所有 Linux 库都必须以lib前缀开头)。

另一方面,C++ 标准库的实现发生在libstdc++或GNU 标准 C++ 库中。这是一个在 GNU/Linux 上实现标准 C++ 库的正在进行的项目。一般来说,所有常用的 linux 发行版都会默认使用 libstdc++。

Mac 和 iOS 实现

在 Mac 和 iOS 上,C 标准库实现是libSystem的一部分,这是一个位于/usr/lib/libSystem.dylib的动态链接文件(在我的mac上的/usr/lib/system目录中有libsystem_kernel.dylib、libsystem_pthread.dylib、libsystem_platform.dylib这三个)。LibSystem 包括其他组件,例如数学库、线程库和其他低级实用程序。

关于 C++ 标准库,在 OS X Mavericks(版本 10.9)之前的 Mac 上,libstdc++ 是默认的。这与现代基于 Linux 的系统中的实现相同。从 OS X Mavericks 开始,Apple 转而使用libc++ ,它是Mac 官方编译器框架LLVM 项目引入的 GNU libstdc++ 标准库的替代品。

IOS 开发人员可以使用iOS SDK(软件开发工具包)进入标准库,这是一组允许创建移动应用程序的工具。

Windows实现

在 Windows 上,标准库的实现一直严格绑定到Microsoft 官方编译器Visual Studio。他们习惯将其称为C/C++ 运行时库 (C/C++ Run-time Library,缩写为CRT),它涵盖了C和C++标准库的实现。

一开始,CRT 被实现为CRTDLL.DLL库(我想当时没有 C++ 标准库)。从 Windows 95 开始,Microsoft 开始以MSVCRT[version-number].DLL(MSVCR20.DLL、MSVCR70.DLL 等)的形式发布它,大概也与 C++ 标准库一起发布。大约在 1997 年,他们决定将文件名简化为MSVCRT.DLL,不幸的是,这导致了令人讨厌的DLL 混乱。这就是为什么从 Visual Studio 7.0 版开始,他们切换回为每个版本提供 DLL。

Visual Studio 2015 带来了CRT的深度重构。C/C++ 标准库实现移入一个新库,即通用 C 运行时库(通用 CRT 或 UCRT,Universal C Runtime Library),编译为UCRTBASE.DLL。UCRT 现在已成为 Windows 组件,从 Windows 10 开始作为操作系统的一部分提供。

安卓实现

Bionic是 Google 为其 Android 操作系统编写的 C 标准库实现,安卓系统底层直接使用它。第三方开发人员可以通过Android 原生开发工具包 (NDK,Native Development Kit)访问 Bionic ,该工具集允许你使用 C 和 C++ 代码编写 Android 应用程序。

在 C++ 方面,NDK 提供了几种实现:

  • libc++,用于 Android 的官方 C++ 标准库,自 Lollipop 和现代 Mac 操作系统开始使用。从 NDK 版本 17 开始,它将成为 NDK 中唯一可用的 C++ 标准库实现;
  • gnustl是 libstdc++ 的别名,与 GNU/Linux 中提供的库完全相同。不推荐使用此库,并将在 NDK 版本 18 中删除;
  • STLport是由 STLport 项目编写的 C++ 标准库的第三方实现,自 2008 年起停用。与 gnustl 一样,STLport 将在 NDK 版本 18 中删除。

我可以用不同的实现替换默认实现吗?

如果你正在处理资源极其有限的系统,你通常希望包含 C 标准库的不同实现。uClibc-ng、musl libc和Diet libc等等,它们都面向嵌入式 Linux 系统的开发,提供更小的二进制文件和更小的内存占用。

C++ 标准库也有不同的实现:Apache C++ 标准库、uSTL或EASTL等等。最后两个实际上只关心模板部分,而不是完整的库,它们的开发考虑了速度。Apache 版本专注于可移植性。

如果我想摆脱标准库怎么办?

不使用标准库很容易:只要不要在程序中导入它的任何头文件就可以了。但是,为了使此操作有意义,你需要自己通过操作系统提供的系统调用以某种方式与操作系统进行交互(这个很麻烦)。正如我之前所说,这是标准库中的函数/方法在实现时使用的。很可能你还必须调用汇编程序来连接硬件设备。

如果这对你来说听起来很令人兴奋,可以看看互联网上的一些人正在尝试在不涉及标准库的情况下创建可以工作的程序。不过,如果自定义一些库,这样就失去了可移植性,因为你依赖于特定操作系统提供的功能。然而,即使是在使用高级库时,艰难的道路也可能会教给你很多东西,并使你更加了解自己在做什么。

除了博学之外,在嵌入式系统上工作时你不希望包含标准库:由于每个字节的可用内存有限,因此你倾向于编写更多的程序集,因为代码不需要是可移植的。演示场景是人们努力将漂亮的视听演示融入有限大小的程序二进制文件的另一种设置——4K 仍然不是最低边界:一些演示方组织了 1K、256 字节、64 字节甚至 32 字节的介绍比赛。那里不允许有标准库!


原文链接:https://www.internalpointers.com/post/c-c-standard-library

什么是C和C++标准库?相关推荐

  1. Go 学习笔记(78)— Go 标准库 net/http 创建服务端(接收 GET、POST 请求)

    使用 net/http 标准库创建一个 http 的 restful api 的服务端,用来处理 GET.POST 等请求. 源代码如下: package mainimport ("enco ...

  2. GCC 连接器、链接标准库 gcc -l、链接手动创建库(指定目录的库 gcc -L)

    1. 链接器 链接器把多个二进制的目标文件(object file)链接成一个单独的可执行文件. 在链接过程中,它必须把符号(变量名.函数名等一些列标识符)用对应的数据的内存地址(变量地址.函数地址等 ...

  3. Go 学习笔记(55)— Go 标准库 sql (初始化数据库、插入、更新、删除数据库表、单行查询、多行查询、事务处理)

    1. 标准库说明 Go 的标准库中是没有数据库驱动,只提供了驱动接口,有很多第三方实现了驱动,我们这里选择 go-sql-driver 这个实现是目前使用最多的.github 地址是:https:// ...

  4. Python 标准库之 subprocesss

    Python 目前已经废弃了 os.system.os.spawn*.os.popen*.popen2.*.commands.* 来执行其他语言的命令,取而代之的是 subprocess 模块. 运行 ...

  5. Python 标准库之 xml.etree.ElementTree xml解析

    Python 标准库之 xml.etree.ElementTree Python中有多种xml处理API,常用的有xml.dom.*模块.xml.sax.*模块.xml.parser.expat模块和 ...

  6. Go 学习笔记(21)— 标准库 os 操作文件(新建、打开、写入、读取、删除、关闭文件)

    Go 操作文本文件时,与其它语言一样也有新建文件.打开文件.写文件.读文件.删除文件等操作.主要有两个标准库来提供这些操作,分别为 os 和 ioutil .在该文中我们介绍 os 模块. 1. 新建 ...

  7. bitset类型, 标准库类型

    C++ primer 17.2 bitset类型, 标准库类型 1 使得位运算更容易实现, 并且能够处理超过最长整型大小的位集合. bitset定义在bitset中 定义和初始化bitset 1 bi ...

  8. c++标准库 及 命名空间std

    1.命名空间std C++标准中引入命名空间的概念,是为了解决不同模块或者函数库中相同标识符冲突的问题.有了命名空间的概念,标识符就被限制在特定的范围(函数)内,不会引起命名冲突.最典型的例子就是st ...

  9. C++标准库简介(转)

    C++标准库的所有头文件都没有扩展名.C++标准库的内容总共在50个标准头文件中定义,其中18个提供了C库的功能. <cname>形式的标准头文件[ <complex>例外]其 ...

  10. pythonurllib标准_Python标准库urllib2的一些使用细节总结

    Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库.这里总结了一些 urllib2 的使用细节. 1.Pr ...

最新文章

  1. MYSQL 联表查询 ORDER 效率低?
  2. java多线程--多线程基础小结
  3. unilever workspace creating space
  4. 微信小程序开发系列五:微信小程序中如何响应用户输入事件
  5. 文本编辑器_markdown编辑器与富文本编辑器优缺点比较
  6. C#中获取路径的几种方法
  7. [转]微信小程序 c#后台支付结果回调
  8. 你可以退部的,不必说抱歉
  9. api 读内存整数_10万+QPS 真的只是因为单线程和基于内存?
  10. Java基础(二):面向对象
  11. infogan 生成mnist 手写数字
  12. C# 图片验证码简单例子
  13. elasticsearch-mathc和term的区分
  14. 表达式运算(包含大整数加减乘)
  15. Vmware搭建软路由教程(Openwrt)
  16. 网管软件 LANDesk的配置(视频配截图)
  17. 如何用Robotics Toolbox 建模多自由度的机械手臂
  18. Java 套接字(Socket)
  19. 瓢城旅行社网页界面设计(HTML+CSS)
  20. Android常用颜色值

热门文章

  1. 专题五 在Cisco Packet Tracer中设计基于 PT 和 OneNet 的智能家居系统
  2. 关于 百度飞浆paddleOCR编译32位版本 的解决方案
  3. 小学加减法教学(9数法)
  4. Linux下的粘滞位详解
  5. 计算机删除用户数据,如何将电脑里的账户信息彻底删除
  6. 要塞十字军东征HD for Mac(即时战略游戏)
  7. opensuse安装百度五笔拼音输入法
  8. 强制卸载某些卸载不了的软件(例如卸载samba)
  9. nRF52832学习记录(十、PWM 脉冲调制)
  10. windows 下运行 UglifyJS