其实一直搞不懂为什么头文件和其他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~

头文件之 为什么不要在我里面声明变量

很多人会想着两个文件使用全局变量,那么这个时候在一个头文件中定义一个变量,在其他文件中包含该头文件不久可以实现了全局的效果吗?

实践后会发现是报错---重复定义。。。

又开始走盲区了

首先是由于头文件中定义,那么当你被多个其他文件包含的时候,编译器会讲变量中的定义都复制一份到各个文件中,而同一个项目中的变量是互可见的,所以就会导致最后的重复定义的问题。

但我又有个疑惑,函数不也是这么操作的吗?为什么函数不报错。

困惑逐渐增多

后来一想,函数是先在自己的文件中搜寻,没有的话才会去其他文件中搜寻,而且你会发现函数如果被实现了,但在自己的文件中再实现一次,也是允许的。而且最后是调用最近的那个函数体。

但又一想,为啥变量不可以这么搜寻???

呀呀呀呀!!!,似乎又陷入死局。

下次再想吧,有点懵了!!!

好像又有希望了!!!

https://zybuluo.com/uuprince/note/81709

原来void a();这种只是声明,但int a;这种就是声明和定义同时。



成功!!!

最新文章

  1. 排序算法----基数排序(RadixSort(L,max))单链表版本
  2. 从Trie谈到AC自动机
  3. 由单例模式学到:lock锁
  4. Scroller 实现的弹性回弹的LinearLayout
  5. Linux系统下如何禁止ping命令或允许ping命令的方法
  6. Tick and Tick
  7. 【PAT Advanced Level】1006. Sign In and Sign Out (25)
  8. BMS 项目过程中遇到的问题
  9. 文字排版--删除线(text-decoration:line-through)
  10. test知识
  11. [置顶] Android的IPC访问控制设计与实现
  12. MFC_Office
  13. 用MyEclipse自动生成hibernate映射文件和实体类
  14. python已安装了DNS处理模块,执行时却报错ImportError
  15. 基于DFS的拓扑排序
  16. 和我一起学习爬虫之HTTP/HTTPS抓包工具--Fiddler
  17. 【Linux】awk指令
  18. javaweb开发.eclipse使用小常识
  19. Java多线程的同步机制(synchronized)
  20. python3.6安装-windows

热门文章

  1. c++ get keyboard event
  2. docker中镜像的作用
  3. for和while的区别及使用
  4. Debug代码调试
  5. dedecms被挂马排毒的过程
  6. OpenStack平台的使用
  7. [bzoj1037]生日聚会
  8. [bzoj5294]二进制
  9. Netty高性能网络应用框架对标P7面试题分享v4.1.70.Final
  10. 柯基数据通过Rainbond完成云原生改造,实现离线持续交付客户