其实一直搞不懂为什么头文件和其他cpp文件之间的关系,今晚索性一下整明白
【c++】解析多文件编程的原理
- a.cpp
#include<stdio.h>
int main(){
a();
}
- b.cpp
void a(){
printf("b.cpp\n");
}
首先看下这两个程序,你们是否存在疑问?这个能编程成功吗,编译成功了,又是否能成功运行呢?那再看看下面这个
- a.cpp
#include<stdio.h>
void a();
int main(){
a();
}
- b.cpp
void a(){
printf("b.cpp\n");
}
下面的是否能成功运行呢?
答案是上面的会过不了编译,下面的可以成功运行
那么你再看看下面的
- a.cpp
#include<stdio.h>
void a();
int main(){
a();
}
如果只有a.cpp文件又是怎么样的呢?
答案是编译可以通过,但过不了链接
我之前就被这些绕来绕去给绕晕了,hhhh~
场景揭密分析
- 首先我觉得这里更多的是有关编译和链接的知识。先看第一种情况,第一种是在a.c中未声明出函数,所以在编译期间就被干掉了。
程序在编译时,会检查cpp文件中是否有某个函数或者变量的定义,如果有,就可以通过编译,不论有没有实现定义。这也就为什么上面会死在编译期。
- 再看第三种情况,有声明,但却没有实现,以至于死在了链接期
程序在编译后,就开始进行链接了,可以想象定义和声明就是一对接口,和动态链接库有点相似。程序在链接期间首先会在自己的文件中拿着函数名,找到对应的函数体。如果在自身的范围内没有找到,就会按指定的查找顺序去找(一般是:文件》项目》环境目录),如果都没有找到就会报错。反馈出链接失败。
- 最后看看第二种情况
上面讲了编译和链接的过程,所以第二种是可以成功执行的。
头文件的工作原理
首先试想编译和链接的关系已经弄明白了。那么就可以知道,使用函数或者其他的东西,需要先声明。那么如果在多个文件中出现多个相同的函数,要你声明的话。你会发现声明了一堆重复但不可或缺的声明。这时候就需要使用头文件了。头文件中主要的目的就是声明,而在编译的时候,编译器会将头文件全部复制到包含文件中,从而实现声明。
之前的我还以为a.cpp和a.h总有种必然的联系。现在终于释然了,Ye~
头文件一般会包含很多声明,当然也可以在头文件直接实现某些定义,但不推荐这样使用。后面会讲为什么不推荐。
头文件之 为什么不要在我里面声明变量
很多人会想着两个文件使用全局变量,那么这个时候在一个头文件中定义一个变量,在其他文件中包含该头文件不久可以实现了全局的效果吗?
实践后会发现是报错---重复定义。。。
又开始走盲区了
首先是由于头文件中定义,那么当你被多个其他文件包含的时候,编译器会讲变量中的定义都复制一份到各个文件中,而同一个项目中的变量是互可见的,所以就会导致最后的重复定义的问题。
但我又有个疑惑,函数不也是这么操作的吗?为什么函数不报错。
困惑逐渐增多
后来一想,函数是先在自己的文件中搜寻,没有的话才会去其他文件中搜寻,而且你会发现函数如果被实现了,但在自己的文件中再实现一次,也是允许的。而且最后是调用最近的那个函数体。
但又一想,为啥变量不可以这么搜寻???
呀呀呀呀!!!,似乎又陷入死局。
下次再想吧,有点懵了!!!