不简单的hello world之C标准库(第一部分)

目录

 

库(Library)

 

1 库(Library)的定义

2 为什么需要库

3 库是如何生成

4 库里面有什么

5 库的分类

6 如何创建库

7 什么是标准库

8 标准库的优点


C标准库

在上一篇文章当中我们分析了hello world这个程序的第一行,那么我们接下就开始看后面的代码,可能有人会说了,这么简单的代码还有什么可看的,同学们,有句话说的非常好,魔鬼在细节,那么这个魔鬼在这里就是printf函数。

printf人人都会用,从写hello world就开始用,用了这么多年简直是使用最多的函数,调试bug的必备利器,但是,亲爱的同学,你有没有想过就是这个我们习以为常当做空气一样存在的的函数到底是怎么实现的,它在哪里被实现的,这个函数的实现文件我们都没有看到过,

那么我们的hello world到底又是怎么调用到这个函数的呢,printf到底是怎么把hello world打在屏幕上让我们看的呢,这些你能详详细细的说清楚吗?如果你还不能清楚明白的解释这些问题,这些问题对你还是一团迷雾的话,那么接下来的我会在后面的文章当中一一为大家详细讲解。

说这些希望大家能保持一颗好奇的心,本质上这也是人类文明得以发展到今天的原因,如果牛顿对苹果落地也像大家对printf习以为常一样,我想万有引力定律可能要向后推迟很多年了,牛顿万有引力的发现绝对是影响人类文明的里程碑事件,具体为什么就不在计算机课程上展开说了,概括的说就是万有引力的发现让人们第一次认识到大自然也是有规律从此解放了长期禁锢欧洲人思想由此诞生了一批猛人极大的推动了文明的发展之类,具体请参考西方历史哲学史自然科学史等一系列史字结尾的书以及类似课程。在这个快节奏高压力的现代生活中,很多人包括我自己有时都会感到迷茫,虽然外在环境如此,写这些还是希望大家能在自己内心能保留一方净土,在这片净土上你依然有着这采菊东篱下悠然见南山的怡然自得,在你深夜加班回家后还能抬头看一看天上的星空,你还能静下心来好好思考一些问题,请保持珍贵的好奇心。

抒情完毕。

现在是时候给大家介绍一下关于这一主题隐藏在冰山之下的一部分,这一部分叫做C标准库(C standard library)。

介绍一下标准库,这个所谓的标准库希望大家能理解一下,所谓标准库,首先它是一个库,那库又是什么呢,计算机科学当中有好多术语,一听上去真的很唬人,这些很唬人的词往往让初学者误以为这个东西一定很高深,很难,而那些已经理解这些词语的人为了让后来者也认为这些真的很高深很难所以往往不做任何解释,其中一些术语你肯定很熟悉 比如这里的库,socket,面向连接,stream等等,我永远都不能理解为什么国内的作者不管是自己写的技术书籍还是翻译过来的就不能好好解释一下这些名词,我觉得计算机学习起来还是有一定的门槛的,这其中的一部分就在于计算机文化方面,这就类似于我们很难理解比如零零后喜欢的二次元,里面有很多术语往往让人一头雾水一样,这些文化上的阻隔会成为进入这个领域的第一道障碍,在这里我会尽力用易懂的方式给大家讲清楚这些很唬人的词语到底是什么意思。

1. 库(Library)的定义


让我们首先来看看到底什么才是库,总结起来一句话就是:

别人(或者自己)已经写好的现成可用的一堆可重复使用的代码

这就是库定义了,这里的一堆代码可以是针对某个特定功能的代码,比如专用于数字分析计算的库,可以是实现某些功能的框架(至于什么是框架呢,见文章末尾),比如一些图形库,Libevent之类,也是可以自己积累的一些小工具,比如实现字符串操作之类功能,这些都可以称之为库。个人觉得其原本的英文更形象一下,Library本来就是图书馆,书库,资料室之类的意思,所以可以形象的把库理解为相关主题的资料,书籍,如果你想了解(使用)一些特定的主题,只需要找相关的书籍资料就可以了,和这里的库的意思是一样的。

介绍完了什么是库,那么你可能会想,到底我们为什么需要用到库这么个东西呢,那接下来首先来回答一下这个很重要的问题。

 

2. 为什么需要库


一个人的力量终归是有限的,我们每个人都不是孤岛,总需要和其它人一起协作来完成某项工作,对于编程,也是同样的道理,如果某些我们需要的功能别人已经实现实现了,我们直接来用就好了。

为什么需要库总结下来就是一句话:

站在其它人的肩膀之上

很明显这里改编自著名大物理学家牛顿的名言,在被问及为什么能取得如此巨大的成就时,牛顿谦虚的说到自己只是“站在了巨人的肩膀之上”,以牛顿学术成就如此之人尚且需要借助于其它人的研究成果,作为平凡的劳苦大众之广大码农更是没有理由不去借助于其它人的代码了。

在计算机世界当中,库,就是其它人的肩膀

我们使用的C标准库,程序所运行之上操作系统(从某种角度上看,操作系统也可以看做库,因为没有操作系统的话,如果我们想运行一个程序还要自己来管理CPU,内存等硬件资源) ,处理网络数据的TCP/IP协议栈(你在写socket程序的时候从没有关心如何处理tcp协议丢包如何处理,如何进行超时重传等等吧,同样TCP/IP协议栈也可以看做是库),因为TCP/IP协议栈已经把这些最复杂最琐碎的工作给你完成了,当你在写自己的程序时只需要专注于完成自己的事情就可以了,其它的事情交给完成特定功能的库就可以了。

所以这下你应该明白了吧,我们每个人都不是万能的,总有我们擅长的和不擅长的,写程序也是这样,比如我需要一些能进行矩阵运算的函数,但是自己实现起来太复杂了,而与此同时又有这样的可以进行科学计算的现成的库,那那我们为什么不直接使用这些已经历经考验的高效优秀的库呢,使用现成的库可以大大加快项目项目的开发进度,目前国内很多互联网公司,很多项目都是直接使用优秀的开源实现,在此基础之上实现业务逻辑,从而实现项目的快速开发,快速迭代,这些都是通过借助其它人的代码来实现的。所以说,某项自己想要的功能如果其它人已经实现了,而且实现的还不错,那为什么不直接只是用呢,而是用其它人的代码多是是以库的形式来使用的,所以:

人生苦短,我们用库

(注意这里的意思是让大家不要去造轮子(库),但是知道一些轮子是如何造出来的还是很重要的,比如操作系统,比如计算机网络,或者对于任何你感兴趣的库我都鼓励大家去看看到底是怎么实现的,但是对于工程项目来说,还是那句话,不要造轮子,除非当前的轮子已经不适用于你的车速了)

我们在这一节中了解了为什么需要库,那么库是如何生成的呢? 接着往下看。

3. 库是如何生成


让我们先来猜猜,库是如何生成,既然我们在上一节中说过,其它人的代码多是以库的形式发布的,那么库就是由代码生成的。可能很多人都说,这不是废话吗,是的,这种看似废话的推理往往都是直白简单的,而简单的东西不容易出错,这种这种不易出错的推理正是我们一步一步进行探索的重要基础。

说到这里就不得不说一下源文件和目标文件(Object File)了。

我们知道,CPU不能执行if...else...,int a = b+c,等等这样的我们人类能看懂的程序,CPU可以执行的恰恰是我们人类及其不容易看懂的二进制指令01011000等等,从这些基本常识中我们就可以知道了,既然我们写的是if...else...,int a = b+c等等这样人类能看懂的程序,而且我们写的这些程序CPU还能运行起来,那么必然需要某个什么东西把我们写的代码翻译成CPU能看懂的01二进制指令,,而执行程序翻译工作的翻译官就是一个叫做编译器的东西,我们写的程序被编译器翻译过来给CPU看的就叫做目标文件(Object File),如图所示:

我们写的每个.c文件文件都叫做源文件,每个源文件别翻译官编译器翻译后生成的文件是目标文件,注意源文件和目标文件是一一对应的。每个源文件当中就是我们写的人类可读的代码啦,而目标文件当中对应的就是CPU可以读懂的二进制二进制指令啦。你可以简单的理解源文件就是中文,而目标文件就是对应的英文,而CPU只能看懂英文(当然,希望有朝一日,CPU也能读懂中文)。

有的同学可能会问,那头文件(include File)呢,请对此还不太了解的同学参考我的上一篇文章叫做《不简单的Hello World之头文件》,那里面会有关于头文件的详细描述。简单的说就是,编译器不会编译头文件,头文件的处理是一个叫做预编译器的东西来完成的。编译器只处理源文件,然后把源文件中的程序翻译成二进制文件生成对应的目标文件。

既然我们了解了源文件以及对应的二进制指令目标文件,那么我们就可以接下里给大家介绍一位计算机世界当中的幕后英雄了,这也是冰山水面之下的一位重量级选手,它就是链接器(Linker)。从名字当中你应该能猜出来它做什么的,链接器嘛,主要就是把一些东西给拼装起来的。链接器拼装的是什么呢,链接器拼装的就是上面我们介绍的目标文件(Object File)。

链接器的作用就是把编译器翻译的多个源文件生成的多个对应的目标文件打包起来生成一个文件。这就是库,从这里同学们应该看出来了吧,库里面包含了我们源文件里的所有代码了,更重要的是,更重要的是什么呢,同学们看出来了吗,更重要的是,这个链接器连接好生成的单独的一个文件库里面已经就是CPU能看懂的二进制指令了,有的同学又会问了,为什么呢,因为链接器连接的是目标文件啊,如图上面图所示,我们上面也说过目标文件里面就是翻译官编译器翻译的CPU能读懂的二进制文件了,既然库里面就已经是程序的二进制形式了,所以这里有一个好处,那就是,当我们使用库的时候就省去了编译这样一个环节,要知道在大型项目中,编译时间动不动就是几十分钟一个小时,所以提前把一些模块编译成库可以极大的缩短编译时间。关于库是如何生成的,这下你应该看明白了吧。这里关于链接器的介绍是很隆重的,但是描述是很简短的,这么重要的利器只简单介绍这么一点这么可以呢,太不给链接器(Linker)面子了吧,别着急,我会在下一篇文章当中用整整一章来给大家详细讲解链接器(Linker),敬请期待。

由于本篇文章较长,我会在下一篇文章当中继续后面的内容。同时希望大家关注我的公共账号:码农的荒岛求生,那里会有最近的系列文章,我会用最直观最形象的方式给大家讲解各种计算机知识,如果哪里没有看明白希望大家能在评论区中提出改进意见,我会持续进行修改,直到大家都能很容易的看明白为止,谢谢大家。

未完待续...

4 库里面有什么

5 库的分类

6 如何创建库

7 什么是标准库

8 标准库的优点

猜你喜欢

转载自blog.csdn.net/github_37382319/article/details/81610138