因为学习中的写代码与我们在公司中写代码是完全不一样的,所以这期来讲解一个模块化设计和cmake多文件编程
开始之前呢,我们需要有cmake,我的是cLion中的cmake(大家也可以用自己的cmake)
我们的 .c 文件是如何生成我们的可执行文件的
我们先写一段 a01.c代码如下:
好的接下来我们直接用cmd进行编译会出现什么情况呢?
直接在这个地方打开cmd
这就出现了一个十分经典的错误也就是“ ** undefined reference to `abc' ** ”我们下面就来解决这个问题。
首先,我先问问大家,请大家想一想,这个代码能不能编译通过,能不能运行呢?
好的,接下来我给大家来用c语言的角度解答一下,可以编译通过的,但是呢,不能运行,为啥呢?因为这里有一个空abc();,运行到这个需要进入abc里面,但是呢我没有abc,所以呢abc就有可能是别人实现的,因为我c语言编译分为两个阶段:第一阶段呢是自己管自己,我编译自己;第二阶段呢就是把我们所以管的人全部汇在一起,来看还差什么东西,没有定义呢报没有定义重复,重复定义呢报重复定义,就是我们可以将这想成一个工厂,我们要组装一个材料,那这个材料的原材料咋提供呢,就是由每一个 .c文件去提供的,那原材料是啥呢,就是由我们.c文件生成的 .o文件(也就是目标文件),
这个就是生成.o文件的过程
但是呢它也没有报错,为啥呢,因为c语言认为abc();是一个函数,但是呢我函数现在没有首地址但是呢,没有事,等到时候所以目标文件(.o)合在一起的时候,在来确定它的首地址
接下来我们用nm来看一下.o文件中的清单
什么是清单呢,首先 .c文件是人能够看懂的文件,那机器能看懂是什么文件呢没错就是.o文件,通过nm呢我们明白我们找不到abc的实现
我们可以看到计算机不知道abc该咋填所以就对abc未定义进行了报错,这说明我们的原材料 .c文件少了,那我们进行一个补充b01.c文件
我们看我们新创建的b01.o文件中的nm,我们看到了abc的实现,那是不是就是可说我们将这两个目标文件(. o文件),交给工厂进行加工,组合一下是不是就明白abc该咋用了
通过对两个.o文件的运行,可以看到我们的“Hello World!和abc都实现了
好的接下来呢,我修改一下b01.c代码
修改成这样,但是呢a01.c的代码不进行改变,并且我将 .o文件, 以及build文件全部删除
生成一个新的 .o ,然后看一下这是b01.o的nm,可以看到abc已经是实现
那么接下来提出一个问题 a01.o和b01.o能否生成的build的文件
ok,我们实践一下
我们可以看到我们的文件生成了,这就可以说明c语言中我们只管有没有abc这个名字(也就是只管有没有符号名),不管有没有参数,那这个时候我们就被坑了,b01呢要东西,也就是参数,但是呢a01不给传东西,我们接下来运行一下build文件看一下
包主在这里是windows系统,要是其他linux或者是苹果电脑会乱打值
我们这里可以看到我们a01.c文件没有传值,那为啥还有值打出来呢,是不是很不明白了,那我们接下来再给a01.o修改一下
然后在编一下a01.c
编译器说什么呢,它说too few,按它的说法abc();这里应该还有一个int a,这说明我们加了一个extern之后我们的编译器就知道了这个错误,但是声明呢也出现问题了,这个函数是b01文件实现的,a01文件如何知道并且加上extern呢,这个时候c语言就提出了头文件的概念,头文件目的就是在一开始就告诉编译器,我从一开始就做了那些准备工作,那我们就建一个头文件b01.h,因为呢这个函数是b01写的,那么这个接口也就是头文件就应该让b01来维护,因为c语言只编.c文件,所以我们除了a01.c文件要加头文件之外,b01.c也要加头文件
为了防止重复呢,加了#pragma once,好的本次的内容也就结束了,谢谢观看!