当前课程知识点:C/C++:从基础语法到优化策略 > Final Exam > Final exam > 2.1 Compile and link
返回《C/C++:从基础语法到优化策略》慕课在线视频课程列表
大家好 今天我们首先介绍一个编译和链接的例子
这个编译和链接的例子呢 虽然在前面我们介绍过
但是呢如果我们的项目有多个文件
比如说是这个样子 在这个里面有两个cpp文件
分别是左边的这个main.cpp和右边的叫matrixop.cpp
我们先来简单看一下这两个文件做什么 就说如果我们有两个cpp文件 我们如何把它编译成一个应用程序
当项目变大的时候我们创建多个代码文件来保存代码 这是非常常见的
那么我们怎么把它编译在一起呢 在这之前我们先看一下这个代码在做什么
首先我们来看main函数
在这里面呢 它首先定义了两个数组pVec1和pVec2 每个数组里面都是有八个元素
里面的内容也是相同的 12345678一直到8 浮点数8
第二个是一样的 那么我们希望计算它们这两个向量的点积
也就是对应元素相乘求和的结果是多少 那么有这么一个函数dotproduct
这个函数它就可以计算两个向量pVec1和pVec2的点积
然后呢把这个结果再打印出来 这是这个程序要做的事情
那么问题来了 dotproduct在哪里定义的呢
实际上我们来看右侧doctorproduct它在matrixop里面是声明了
这个它的反馈值是float 有三个参数 第一个参数是length 第二个是float指针类型 第三个也是float指针类型
那它的实现文件在哪里 它的实现文件实际上是在右下角这个matrixop这个cpp里面
在这里面呢 它的实现那就是对应元素相乘嘛 我们来看float sum=0先初始化
然后int i=0到它的长度 这个意思就说右边这两个数组
a和b它们的长度是多少 也就是里面有多少个元素
那么把所有的元素全遍历一遍 对应元素相乘 然后累加到sum上面去
这样的话累加起来之后 那么再把结果返回回来 这么一个简单的函数
这样的话 其实也就说我们在编程的时候 把数学相关数学运算相关的
这些模块或者这些函数 我们可以放到一个单独的cpp比如说叫matrixop 跟矩阵操作相关都放在这里面
那么这里面实现的函数呢 我们就把它的声明放到头文件里面去
那么这个头文件在编译的时候我们可以直接
编译这个main.cpp和matrixop 我们来看看怎么去编译它
首先呢 我们先编译第一个main.cpp 我们来看是这样的
g++ main
哦在编辑之前呢 我们先看看这个目录下面有三个文件
main.cpp matrixop.cpp和matrixop.h这么三个文件
先来编译一下 编译的话是用gcc来编译 如果我们只是编译不链接要加-c这样来
如果你不加的话 那会怎么样
你不加的话 实际上就说要它把cpp编译然后链接成一个应用程序
我们如果是这样去执行 它会报错 为什么
它会报一个链接错误 Undefined symbols
哪一个呢 就docproduct 它说这个东西没有定义
如果我们刚才这个命令g++编译cpp它要去编译的时候 它会发现这个函数的实现找不到
也就是说它想用这个函数去做一些事情 但是这个东西这个函数是做什么的它是不知道的 所以说
这里面就说那要怎么办 我们可以先编译它 只编译不链接
gcc -c这样的 我们来看 左边显示我们出了一个main.o文件就出来了 我们再来看g++ -c
就是只编译不链接 matrix把另外一个cpp也编译一下 然后我们看这时候又出来
一个matrixop.o文件
这样的话我们通过这两次gcc g++的这个命令 我们就生成了两个object文件
那么怎么链接呢 我们链接可以继续用g++来链main.o matrixop.o
然后呢
把它们链在一起生成输出文件 输出文件我们可以随便起一个名字
比如说 我们就叫它dotproduct了
编译完之后我们可以看到 这个目录下又生成了一个可执行文件
这个可执行文件就是dotproduct 然后呢我们去运行一下它 dotproduct那它应该是运行这个结果吧
点乘的结果出来 那我们运行
好 那他的结果是204 大家可以自己算一下是不是204
这是这样的
这里面我们可以看到还一个点呢 就是在main.cpp里面我们有一个include "matrixop.h"
matrixop.h实际上是在这里 就是它这里面这个文件里面只有一行
float dotproduct是一个声明 那么如果没有这个 我们不去做include把它注释掉 保存
注释掉之后如果我们再去编译 会怎么办
我们再回来 刚才编译的时候如果我们再去编译main 它就会报一个错误error
use of undeclared identifier 'dotproduct'
它也就是说它这下面有提示 就这个绿色箭头指向dotproduct是没有声明的
它不知道这是个什么东西 因为这次编译它只是输入了
这些代码 那这个时候呢
它就不知道你这dotproduct是什么
嗯我用的这个VS Code这个IDE也是比较聪明的 它提前就在这打了一个下划线
你告诉我说 这个
是不存在的 就未定义的标识符 如果你发现未定义的这个
这个标识符的话 这种错误表示的是编译错误
然后你把它这个去include进来编译错误就会消失
然后我们再来编译一下编译错误就会消失 但如果你链接的时候只用这个 那它会产生链接错误
那么这地方有个ld
这是链接器 symbol(s) not found 那就说明这是一个链接错误
啊这个呢
大家编程的时候要区分
编译错误还是链接错误 编译错误一般是指你的代码写错了 分号少了一个 括号少了一个之类的造成的
就是你的这个语法是有问题的
那么链接错误呢 实际上是在多个object文件之间 它们之间存在依赖 比如说我们的main.o实际上是依赖
这个matrixop.o 那么这个依赖被破坏了 那么它也会报链接错误
这是这个例子啊 好
-Quiz 1
-Quiz 2
-3.3 Relational expressions (> < ==)
-3.5 Branching statements (if else)
-3.8 break and continue statements
-Quiz 3
-4.4 Structures, Unions and Enumerations
-Quiz 4
-5.3 Allocate memory: C++ style
-Quiz 5
-6.3 Recursion and pointer to functions
-Quiz 6
-Quiz 7
-8.1 C/C++ with ARM development board
-Quiz 8
-9.2 Constructors and destructors
-Quiz 9
-10.1 Operators in cv::Mat in OpenCV
-10.4 Automatic conversions and type casts for classes
-Quiz 10
-11.1 Dynamic memory and classes
-11.2 New and improved String class
-11.3 Using pointers to objects
-Quiz 11
-12.2 Static and dynamic binding
-12.3 Access control: protected
-12.4 Inheritance and dynamic memory allocation
-Quiz 12
-13.1 Constructor and assignment
-13.2 Classes with object members
-Quiz 13
-14.1 CNN for image classification
-Quiz 14
-15.3 RTTI and type cast operators
-Quiz 15
-Final exam


