当前课程知识点:面向对象程序设计(C++) > 第一讲 课程简介与编程环境 > 1.1 编程环境与工具 > 多文件编译链接的方法
好 在上一小节呢
我们教给大家怎么把一个源代码
变成多个源文件
那很显然当我们做了这样的工作之后
在最开始我们学习的编译链接对于单个文件
进行操作的那种办法
就不太适用了
我们对于有多个源代码的这个程序
我们怎么把它编译链接成我们最后的可执行代码呢
这就是我们这一小节要给大家来介绍的
就是多个源文件
它的编译和链接
我们会讨论3种不同的办法
第一个 就是使用控制台的窗口
我们通过手工的输入这个命令
来做这个事情
就像大家看到的这个例子这样子
当然这个例子我们截的图是Windows平台下的
当然我们这个平台这么来切换
其实也是给大家告诉你
你用什么平台去编程序其实都没关系
像前面我们看到的例子是
苹果电脑上截换的
那现在看到的是Windows上截的
其实也是给大家做一个示范
这都没关系
我们都可以用它来
作为我们学习编程的一种环境和平台
好那么在Windows下面我们用的是
装的是微软的这个Visual studio这样一个
编程的环境
那么配置好了之后呢
它会允许你在命令行上
在控制台里头去输入这个编译链接的命令
来把你的源代码
变成可执行的程序
那么可以看前面这一个
红框框住的部分 cl
就是跟我们前面讲的
苹果电脑上用的g++那个是类似的
是微软所提供的一个
编译链接我们C++代码的一个工具
它叫cl
然后后面是它的一个选项-gx
然后是我们的源代码
我们可以看到呢
当我们的源代码变成多个cpp的时候
你只要在命令行上
把这些源代码的名字写上去
这个文件名写上去
依次列在上面就可以了
后面是-o ex5.exe
就是编译链接之后产生的可执行程序的名字是什么
在windows下面一般可执行程序的名字
它的后缀都是exe
所以我们这是-o ex5.exe
经过这个指令
我们一回车
你会看到下面的这个信息
就是它的编译链接的一个提示信息
完了之后又出现空台的这种提示符
然后我们输入ex5
这个可执行程序的名字
后缀名.exe可以不写
当然你写上去也对
所以你既可以敲ex5
然后回车来执行这个程序
也可以输入ex5.exe
然后回车
效果是一样的
大家底下可以去试一下
那么最后运行结果是它出现一个提示信息
这是我们的第一种方法
在命令行上通过手动
把你拆分出来多个源代码的名字
送进去让它编译链接
最后得到可执行程序
第二个办法可能更多的人也许更愿意的一种办法
就是我们称之为是一个集成开发环境
有的时候就是那种图形界面
那么下面大家看到的这个截图
是VC6这个工具它的一个截图
其实呢大同小异
可能名字上会有略微的差别
这个菜单上可能有些变化
但是这个基本的思路是一样的
都是有一个称之为工程的
一个菜单选项
那么呢你把你的这个任务
命名为某工程
给它取个名字
然后把你拆开成为多个源代码的那些
各个源代码的cpp文件
通过添加的办法
比方说像这个例子里头
它就是添加文件到工程
那么它会弹出一个对话框
让你去选择
你就把你拆开成多个源代码的那些文件
比如说在这个例子里头
它是ex51.cpp
ex52.cpp
一共两个
把它依次的加进去
就像这个右下角大家看到的
在这个工程ex52里头
有两个源代码
这两个源代码是你整个源程序的两个部分
现在通过这种方式加进去了
那这个集成开发环境就知道
我要编译你这个可执行代码
需要用到两个cpp
它自己会做好编译链接的这种工作
第三个办法就是使用一个make这种工具
那这个方法呢
也是我们在网上大量的开源工具
大家去下载去使用的时候
所经常用到的这种方法
那它当然有一些特殊的好处
否则的话也不会这么流行
所以我们下面就给大家讲讲
这个方法是怎么来实现
多个源文件的编译和链接的
这也是我们强烈或者主要推荐的一种办法
首先用这个工具
需要我们除了源代码之外
还要再去写一个
有特定格式要求的
一个文本文件
一般我们把这个文本文件
称之为makefile文件
它的文件名可以任意的取
但是很多时候
大家都取的是默认的名字
就大家约定俗成的
就把这个文件取名为叫makefile
所以你去随便找一些开源工具去看看的话
你会发现这里头
大家都用的这个名字
这样的话便于交流便于理解
第二个呢就是我们要说到的
这样的一个工具或者这样一种办法
为什么它如此流行呢
因为它是我们进行大型的编译工作
把它进行自动化完成的时候
一种非常有效的一种工具
它可以减少我们编译程序花费的时间
也可以确保我们使用正确的选项进行编译
而且能够保证我们链接正确的程序模块程序库
而且基于这个make的这种机制
make是个工具的名字了
基于它的机制其实我们还可以干一些别的事情
比方说我们可以减少任务的重复执行过程
我们可以减少说明文档的工作量
因为你的makefile里头这些指令
本身就具有这种帮助文档这种作用
所以你额外的文档就可以减少了
再一个当然你还可以实现出一些
其他的创新性的想法
就是说
make这工具
不仅仅可以用来编译你的源代码
还可以干一些别的
那能干什么呢
这个可以作为课后的思考题
你们自己通过网上去搜一搜问一问
看看它还能干什么
那好百闻不如一见
我们来看看一个makefile的文件示例
这个示例大家可以看到
是我们07年的时候我写的一个代码
那这里头我通过不同的颜色
对它的各个部分做了区分
首先点上最前面的三行
是用#开始的
它是一个绿色的部分
这是叫做注释
所以这个格式的文件
它的注释是用#来控制的
我们在C++里头注释是用两个除号来做的
当然C++里头还有一种就是用/**/来把它括起来
也是可以做注释的
它不同的语言它注释的这个格式是不同的
在makefile里头注释是用减号
往下红色的部分
我们可以看到几个字符串
一个叫all
一个叫main.exe
一个是clean
这个红色的被称之为任务
就是我能够完成哪些任务
它的名字
这个名字可以任意的字符串
比方说前面这个all是个单词
main.exe呢
看上去像个文件的名字对吧
然后test.exe呢
也是好像是一个执行程序的名字
然后最后clean又是一个单词
那么这个任务放在这个一行的起头
然后用冒号把它隔开
在冒号的后面
这个黑色的部分
我们称之为完成这个任务的条件
比方说我要完成这个命名为all这个任务
需要什么呢
需要main.exe和test.exe
这两个从哪里来的呢
当然现在这个地方是没有的
那我们往下看可以看到
main.exe和test.exe是另外两个任务
它产生的
那在main.exe这个任务里头我们看到
它所需要的是
main.cpp
student.cpp
也就是说只要有这两个cpp
我就具备了去完成main.exe这个任务的前提
所以我们把这个黑色的
跟在冒号后面的
称之为是它的条件
从我们这个例子可以看到
这个条件通常都是源文件的名称
这是第一
第二
这些原文件之间是用空格分开的
也就是你为了去得到main.exe
这样的一个可执行的代码
我需要有main.cpp和student.cpp
这是一个例子里头用到的两个cpp
它源代码拆成这两个了
需要有它
那么有了这两个
我就可以去完成这个main.exe
怎么完成呢
因为这个黑色的部分
它只是冒号后面的这个部分只是它的前提条件
怎么去完成它还没说呢
那就是下面我们看到的
这个淡绿色的这个文字
也就是完成任务的它的步骤
在这个例子里头
我们的完成的步骤很简单
每一个任务都是一个步骤就完成的
其实它可以有多个步骤
10个8个100个都没有关系
那么依次写在下面
每一个步骤一行
而且每一个步骤
这里头就提到了
我们这个makefile它的格式
在我们的任务它是顶行写的
那么这个步骤呢
要求必须用键盘上的Tab键
也就是那个制表符
然后空出前面的一列
也就是你的每一个任务它的那一行
它的步骤每一个步骤它的那一行
前面都是一个Tab字符
所以你会看到在main.exe main.cpp student.cpp
这个前面空了那么一个缩进
这个实际上是按Tab键做的
不可以用空格
所以这个地方特别强调一下
它的格式要求必须是一个Tab键
然后就开始写你的
完成这个任务的步骤
那像现在的main.exe
这个任务要完成的时候
它是用12:00 这个命令来完成的
所以呢 它步骤的写法就是g++
点点点点 一些文字
对吧 那我们这个地方
为了输出main.exe
它的写法是-o main.exe
然后用到了你的两个源代码
这就是完成main.exe
它所用到的这个步骤
下面的这个test.exe 也是类似
最后一个任务
clean
我们补充一下这个只是我们的一个例子
并不是你做你的
写你的makefile 的时候
也得跟这一样
不是这样子的
这是在这个例子里头它恰好是有4个任务
你的工作里头到底有多少个
你自己来定
那我们看最后一个任务叫clean
冒号后面是空的
那就意味着完成clean这个任务
不需要任何基础
直接可以来完成它
怎么完成的呢
我们看它下面的这个指令
是del *.obj *.exe
这是一个windows平台下的
删除文件的一个指令
del 就delete的一个缩写 del
它的意思是说
把当前目录下面
后缀名为obj
后缀名为exe的
这两类文件
把它删除掉
所以顾名思义
它的任务叫clean
就是这么来的
就是把我源代码之外的
通过编译链接所产生的这种文件
我不要它
把它清掉
只保留cpp
只保留.h文件
就使得它更干净了
所以把这个任务叫clean
那么通过这个例子我们可以看到
这个makefile的写法
其实很简单
就是任务名
冒号 前提条件
前提条件往往就是你的源代码的名字
源代码文件的名字
然后下面是Tab键隔开的一个一个的步骤
对于我们编译来讲
对于我们这个课程来讲
编译的指令很简单
所以通常是这个步骤只有一步
就是你的编译指令
就原来我们在命令行上要去敲的那个东西
你事先写到这个文件里面去
比如像刚才写的
g++ -o main.exe main.cpp student.cpp
本来这个是按照我们第一种方法
是你自己在命令行上敲进去的
每一次都得自己敲
但是现在有了makefile之后
你只用写一次
把这makefile文件存起来
以后就去让机器去执行它
怎么执行呢
我们看
它有一些不同的办法来执行
首先需要到控制台上
这个窗口里头去执行它
所以你在不同的操作系统下面
去打开这个源代码所在的目录
去打开控制台窗口
然后在里头输入命令
下面有4种不同的方法
第一个最简单了
直接敲make
这是一个工具的名字
一回车
它就开始执行
在这种话情况下你没有代任何的参数
它执行什么呢
它执行你第一个任务
刚才那个例子里头我们第一个任务叫做all
它就执行那个
第二种方法
make任务名
比方说make clean
它就执行这个makefile文件里头的clean这个任务
make text .exe
它就去执行
那个叫做text.exe的那个任务
这是第二种方法
就是make加上任务名
第三种呢
大家注意到
我们刚才教敲make的时候
那这个工具它怎么知道去找哪个文件呢
这就是约定俗成它规定好
当你没有给出这个文件的时候
它会去找名字叫做makefile的这种文件
所以方法一方法二里头
都是去执行那个代码里头的指令
有的时候你的这种makefile的文件
可能不叫那名字
那我想去执行我自己命名的那种文件怎么办呢
这就是方法三
我们看到的用-f这个参数
后面跟上你makefile的名字
比如说下面这个绿色的这个例子里头
make -f my_mkfile
你看这个名字
就是我自己取的
那它里头也是参照刚才那个例子一样
里头有任务 冒号 前提条件 步骤
都是如此
但是它的名字不叫makefile
它的名字是my_mkfile
这是我自己取的
怎么告诉make这个工具去找它呢
用-f这个命令
就参数去自己查清了
当然我们也可以把123这种方法
把它结合起来
方法一方法二方法三结合起来
那就是方法四大家看到的
既可以用-f
指定这个makefile的名字
又可以在后面指定说
执行这个文件里头的
这个命令集合里头的哪一个任务
就像大家看到的
make-f my_mkfile test.exe
就执行这个makefile文件里头的
叫做text.exe的这种任务
所以这四种方法都可以
当然根据你的实际情况来选择
一般来讲
你如果没有特殊的需要和特殊的原因
通常会把这种指挥它去怎么编译链接的那个文件
直接就用makefile这样的名字来做它的命名
如果是这样子的话
通常用方法一方法二就够了
而且对于我们课程来讲
一般来讲大家的第一个任务
或者说也可能是你唯一的一个任务
就是去生成可执行代码这个任务
所以呢这个任务往往是放在第一个
在这种情况下
可能大家用到最多的
就是方法一
直接在控制台里头在命令行上
敲make 回车
你就会产生你的可执行代码
我们看看这样的一个截图
这个截图我们又切换到苹果电脑上来了
我们可以看到
ls显示当前目录下面
有1234四个文件
分别是func.cpp func.h main.cpp
还有一个叫做makefile的文件
这个文件内容是什么呢
我们用cat这个命令
可以看到
它里头有1234四行代码
不包括空行有四行
我们可以看到
它的第一行是一个名字叫做ex5的
一个任务
然后冒号
它需要有三个文件
做它的前提条件
它的任务是怎么完成的呢
只有一步
就g++ -o ex5.out main.cpp func.cpp
把它编译成一个ex5.out
这样的一个可执行程序
然后第二个任务叫clean
就是把你生成的这个out文件给它删掉
那么在苹果电脑上这个系统上面
它要删除一个文件
它的这个命令是rm
这个信息为了让它不输出
所以前面会加一个@符号
如果你不要它的话
它会提示在执行的时候会给出一个提示信息
如果你不想看到这个提示信息
可以在前面加上一个@符号
所以这个@符号起的这个作用
真正的命令就是那个rm
好 我们可以来执行一下它
make空格ex5 回车
这就是我们前面讲的方法二
make空格任务名字
在这个里头任务名子叫ex5
所以它就把这个ex5这个任务
进行了一个执行
经过执行之后
我们看到它给出一个提示信息
g++ -o ex5.out main.cpp func.cpp
完了我们用ls
可以看到在当前目录下面
多了一个ex5.out这样的一个文件
然后我们可以执行它
它会给出一个提示信息
然后我们可以执行
第二个任务
make clean
执行完了之后你再敲ls
看当前目录里头发现
少了一个文件
那个ex5.out没了
因为clean 这个任务
它的工作就是把这个ex5.out给它删除掉
然后我们可以去尝试方法一
直接敲make回车
你可以看到
它跟你去敲make ex5是一样的
因为ex5这个任务是第一个任务
所以你不写这个任务的名字
它也会执行
这就是你用make它的这个不带参数的时候
执行的这个结果
我们可以看到呢执行它之后用ls
一样的能看到这个ex5.out
这个文件生成出来了
-1.0 课程定位、教学内容
-1.0 课程定位、教学内容--作业
-1.1 编程环境与工具
--源程序拆分
-1.2 main函数的命令行参数
-作业一--作业
-2.1 变量定义
--变量定义
-2.2 变量的初始化、类型推导与基于范围的循环
-2.3 函数重载
--函数重载
-2.4 函数参数的缺省值与追踪返回类型的函数
-2.5 类的定义
--类的定义
-2.6 类成员的访问权限与友元
-第二讲 基础语法(1)--作业二
-3.1 构造函数析构函数
--构造函数析构函数
-3.2 赋值运算符重载
--赋值运算符重载
-3.3 流运算符重载
--流运算符重载
-3.4 函数运算符重载
--函数运算符重载
-3.5 下标运算符与自增减运算符重载
-3.6 静态成员与常量成员
-3.7 对象组合
--对象组合
-3.8 移动构造函数
--Video
--Video
-3.9 default修饰符
--Video
-第三讲 基础语法(2)--作业三
-4.1 继承
--Video
-4.2 函数重写
--Video
-4.3 虚函数
--Video
--Video
-4.4 自动类型转换
--Video
-4.5 禁止自动类型转换
--Video
-4.6 强制类型转换
--Video
-4.7 函数模板
--Video
-4.8 类模板
--Video
-4.9 成员函数模板
--Video
-4.10 模板特化
--Video
-作业四--作业
-5.0 引言
--Video
-5.1 从FOP到OOP
--Video
-5.2 对象在哪里
--Video
-5.3 接口在哪儿
--Video
-5.4 实现接口
--Video
-5.5 变与不变:多态的威力
--Video
-6.0 引言
--讨论
-6.1 从负载监视器的设计开始
-6.2 接口的分离与单一责任原则
-6.3 委托与接口的进一步分解
-6.4 分离不同层面的可变性
-7.0 引言
--Video
-7.1 迭代器
--Video
-7.2 迭代器的实现
--Video
-7.3 迭代器与模板
--Video
-7.4 算法与数据的解耦
--Video
-7.5 抽象结构与类模板
--Video
-7.6 函数对象与算法分解
--Video
-7.7 基于模板的策略模式
--Video
-8.0 引言
--Video
-8.1 已有资源的组合
--Video
-8.2 适当引入接口
--Video
-8.3 接口不变时的功能变化
--Video
-8.4 装饰
--Video
-8.5 责任的传递与责任链
--Video
-8.X 小结
--Video
-9.0 引言
--Video
-9.1 通过封装增加隔离、应对变化
--Video
--Video
-9.2 增加抽象层,应对变化
--Video
--Video
-9.3 相互关联对象的创建
--Video
-9.4 示例:自动组卷系统设计
--Video
-9.5 设计思路(上)
--Video
-9.6 设计思路(中)
--Video
-9.7 设计思路(下)
--Video
-9.X 小结
--Video
-课程总结
--Video
-期末考试--作业