【补充阅读】程序的生成原理:概述 #148
RicoloveFeng
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
今天的课上讲述了 Linux 下开发程序的过程,可能很多同学听不明白,在这里我们做一些补充。
解释型语言和编译型语言
在 SICP 中,同学们只需要在 .py 文件里面写好你的代码,然后让 python 去运行就完成了。
不严谨地说,你可以把 python 看成是一个独立的程序。python 会逐行阅读你在文件里写了什么,然后做对应的事情。
也正是如此,在单步解释器里面,你可以去定义一个函数,只不过缩进打得累一点。
在这个过程中没有任何的编译。python 就像一个代理人,你告诉 python 干什么,python 理解之后,再告诉机器干什么。
然而,当我们写 C/C++ 程序的时候,并不存在这么一个代理人。编译 C++ 程序会直接生成一个可执行文件。当你运行这个程序的时候,就直接把程序交给机器。机器直接阅读程序内容,然后按部就班地执行。
这就是 python 和 C++ 的区别。
从源代码到程序
机器和 python 不一样,机器并不能直接看懂你写的 .cpp 文件。这就是为什么我们需要编译器。
无论是用 Visual Studio ,还是用 g++,将 .cpp 文件转换成可执行文件,就需要以下几步:
什么是非集成开发环境
前面说到,制作一个程序,你需要经过【源代码编写->编译为机器代码->运行程序】的过程。
在集成开发环境下,整个过程被整合到了一起。你只需要在 Visual Studio 或者 DevC++ 提供的文本编辑器里面写好 C++ 程序,然后点击按钮,程序就完成运行了。
太快了!很方便!
但是这并不是程序唯一的生成方式。在 Linux 系统下,每一个步骤都能拆分出来。
hello.exe这样的,那么你只需要【双击】,就可以运行。而在 Linux 下,一个文件是不是可执行文件,并不取决于后缀,而取决于文件的内部属性(
ls就是靠这种属性给不同的文件加上不同颜色的)。如果一个程序
program可以执行,那么在终端里,就可以用./program的方式来执行它。所以将 WIndows 程序移植到 Linux 下,其实就是让大家不要去点那个 Visual Studio 提供给你的按键,而是学会用命令行工具,一步步地把可执行文件生成出来。
使用 g++
g++ 和 python 一样,也是一种在终端使用的命令行工具。既然是命令行工具,就需要在命令中告诉工具「该干什么」,「有哪些参数」。
前面我们提到,生成程序有【预处理 -> 编译 -> 连接】三个步骤。在助教给的 Makefile 中,有如下几条命令:
这实际上就是完成了【预处理 -> 编译】这个步骤,将
Func1.cpp转化为了底层代码Func1.o。但是注意了,这还没到连接这一步,因此几个
.o文件都是不能运行的。真正完成连接的是这条:这条指令告诉 g++,把
Func1.o Func2.o Func3.o main.o以及command.h四个文件打包成main这个文件。g++ 的可用参数其实很多,后续大家学习会接触到,这里我们其实并不需要非常了解怎么使用 g++,直接按模板去写也没有问题。
Makefile 的工作原理
Makefile 实际上就是
例如,我想做一个麦辣鸡腿汉堡,我就要在我的 makefile 里面这么写:
结果后厨一看,面包有了,青菜有了,但是没有炸鸡腿排,只有裹粉生鸡腿排。
于是,我们在 makefile 加一条:
下次我们再让后厨做麦辣鸡腿汉堡,如果他发现没有炸鸡腿排,他就会发现 makefile 已经告诉他怎么获得炸鸡腿排。
换到程序里面,
make就是后厨,它看我们写的 makefile 来做程序。我们打包可执行文件,就像是要做一个最终成品:此时 make 就会去确认
Func1.o Func2.o Func3.o command.h main.o是不是都在。当然,一开始并没有任何的
.o文件,因此 make 就会按照 makefile 的余下部分去进行制作。这也是为什么我们说这里有一个「依赖树」,因为你需要从最原始的材料一步一步搭建程序,而 makefile 就指定了搭建顺序。
Beta Was this translation helpful? Give feedback.
All reactions