程序员应该如何理解标准库

 2024-02-21 04:01:19  阅读 0

作者丨码农的荒岛求生

来源丨码农的荒岛求生

记得学习C/C++语言后,我一直有这样的疑问。 C++中常用的函数和cout函数在哪里实现?

我相信我不是唯一有这个疑问的人,这篇文章将回答这个问题。

C/C++语言是如何实现的?

相信有的同学一定觉得编程语言很神秘,但事实上并非如此。

编程语言的本质是什么?

本质上,语言只是一堆规则,就像汉语的主谓宾一样

有的同学可能会问,为什么一定要有这么一堆规则呢? 事实证明,只有有了规则,编译器才能知道如何处理我们写的程序

编译器在遇到后知道是否必须后跟左括号,后跟 bool 表达式,然后后跟右括号。

如果我们编写的程序不满足这些规则,结果就是编译器开始抱怨编译错误。

我们回到主题。 事实上,C/C++和任何编程语言都是这样的一堆规则。 对于C/C++来说,每年组织上都会有一群人呼吁(ISO)制定C/C++语言规则,所以这群人坐下来讨论的一堆规则实际上就是一个标准。 每次讨论都会重新修改和制定新的标准并向外界发布。 这就是为什么C/C++有各种版本:C99、C11、C++03、C++11、C++14等。这些数字实际上来自标准制定的年份。

发布的标准包含两部分:

C/C++ 支持哪些功能?

C/C++ API,程序员可以在自己的C/C++程序中直接调用这些API,这些API被称为标准库( )

请注意,已发布的标准仅定义了 API,但不包括实现。 有同学肯定会问,那么标准中定义的API由谁来实现呢?

C/C++标准库的实现

至此,我们终于可以开始讨论标准库的实现了。 事实上,有一群人负责根据发布的API来实现标准库。 程序员实现时,除了一些数学计算,比如文件读写、内存分配、线程创建等相关API之外,这些程序员还必须依赖相应操作系统提供的功能。 那么这些程序如何使用操作系统提供的功能呢? 答案是使用(Call)。 注意,很多同学可能没有意识到这一点,但这非常重要。 也就是说,我们编写的很多代码依赖于操作系统。 操作系统实际上提供了很多功能。 程序员使用这些功能的方式其实就是使用系统调用(关于系统调用,博主在《》的“”部分有详细的解释)。

所以我们知道,其实每个平台(操作系统)都有自己特定的标准库实现,因为不同的操作系统提供的功能不同,所以提供的系统调用也不同。

现在我们可以回答原来的问题了。 原来cout等代码都是在标准库中实现的。 那么这些标准库在哪里呢? 我们的程序如何使用标准库呢?

标准库在哪里? 如何使用?

让我们用C语言编写一个简单的Hello World程序:

#include 
int main() { printf("hello world\n"); return 0; }

然后编译并执行:

$ gcc helloworld.c -o hw$ ./hwhello world

我们可以看到程序运行正确,但是问题来了。 既然我们知道它实际上是在标准库中实现的,那么在这个过程中标准库是从哪里来的呢?

要回答这个问题,我们需要知道编译可执行程序的一个过程:链接。 博主在《》系列文章中对链接有详细的解释。 简单来说,链接的作用就是将程序所依赖的库进行打包。 要查看可执行程序依赖哪些库,我们使用一个名为 ldd 的工具:

$ ldd hw    linux-vdso.so.1 =>  (0x00007ffe075d3000)    libc.so.6 => /usr/lib64/libc.so.6 (0x00007fcd58b75000)    /lib64/ld-linux-x86-64.so.2 (0x000055c5dbea4000)

我们注意到可执行程序hw依赖于一个名为libc.so.6的库,位于/usr/lib64/libc.so.6。 这个libc.so.6就是我们要找的标准库。

Linux中以.so结尾的文件称为动态链接库。 难怪我们看不到标准库的实现。 本来都是实现并打包成动态链接库的。 有关动态链接库的详细信息,请参见“”。 简单来说动态库包含编译好的二进制程序,但是与可执行程序相比,我们无法直接运行动态库。

既然我们知道了标准库是什么,在哪里,可能有同学会问,那么我们如何使用标准库呢?

原来编译器gcc在编译程序时默认会自动链接标准库。 因为大家在编写程序时都避免不了使用标准库提供的API,所以gcc等编译器会自动将标准库打包成可执行程序。

现在你应该明白了。

接下来我们看看标准库在各个平台下的实现。

Linux标准库的实现

Linux下标准库的实现称为GNU C,也称为glibc。 想必有些同学听说过这个名字。

glibc是Linux平台上使用最广泛的。 然而,有一段时间,Linux发行版中的标准库大多使用Libc。 经过几年的发展,glibc 开始超越 Libc,Linux 发行版开始转回 glibc。 ,现在在Linux发行版上,您将在磁盘上看到一个libc.so.6文件。 该文件实际上是 glibc 的现代版本,但名称遵循 Linux 发行版的约定。

C++的标准库是用++实现的。 在Linux平台上使用ldd工具可以看到这个标准库。

标准库实现

标准库的实现与微软的官方编译器捆绑在一起。 标准库曾经被称为 C/C++ Run-time (CRT)

微软从一开始就采用+版本号.DLL的命名方式来发布,并于1997年简化为.DLL。

2015年起,中国C/C++标准库被称为C(简称CRT、UCRT),即.DLL。 此后,该标准库随Win10一起发布。

总结

看似简单的问题实际上往往并不那么简单。 在这篇文章中,我们从一个简单的问题出发,继续探索其背后涉及的方方面面。 希望本文能够帮助您彻底了解标准库。

标签: 标准 操作 程序

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码