c/c++工程中为什么仅仅main.cpp引用其他源文件的头文件不够,源文件还要引用自身的头文件?
原博客链接:
https://blog.csdn.net/khwkhwkhw/article/details/49798985?utm_source=app&from=timeline
引言:
我们经常在c工程中发现,源文件中要包含自己的头文件。一直以来,都不知道为什么这样做。现在,我知道了。
以前的认知:
我认为,.c文件没有必要包含自己的.h文件。.h文件包含.c文件中定义的函数和全局变量的声明,.h文件就是.c文件提供的对外接口文件。既然.h文件就是.c文件提供的对外接口文件,那么.c文件就没必要包含自己的.h文件了(.h文件是对外提供用的,对内又何必再包含进来呢)。
鉴于这样的理解,我对于工程中.c源文件包含自己的.h头文件很是不理解,不知道为什么要这样做。
现在对此的理解:
但是现在,我知道为什么要源文件包含自己的头文件了。
如下,一段书中的原话:
“如果希望让编译器检查声明的一致性,一定要把全局声明放到头文件中。特别是,永远不要把外部函数的原型(也就是函数声明)放到.c文件中:通常它与定义的一致性不能得到检查,而矛盾的原型(也就是函数声明)比不用还糟糕。”
注意:外部函数的原型,就是外部函数的声明。
对这段话的理解:
为什么:“永远不要把外部函数的原型放到.c 文件中”
这个外部函数A指的是B.c文件之外定义的函数,B.c文件中需要使用外部函数A,就需要先对外部函数A声明(对外部函数的声明就是外部函数原型)。对这个外部函数A的声明,不能放在B.c文件里面来实现。
以实例说明:
①假若工程中有2个源文件a.c和b.c;a.c的头文件为a.h,b.c的头文件为b.h。
②a.c中定义了一个函数sum。
③b.c要引用sum这个函数。做法是:在b.c中声明sum这个函数。然后b.c就可以使用sum函数了。
这样的做法就是把外部函数sum的声明放到了b.c中来。然而,这样的做法很不妥。
不妥的原因:
sum是在a.c中定义的,而声明确是在b.c中,sum函数的定义和声明不是在同一个文件中的。定义和声明不在同一个文件中,编译的时候,编译器就不能对定义和声明的一致性进行检查。这样,如果sum的定义和声明不一致,编译器就无法检查出来(定义和声明不在同一个文件中),那么编译的时候不会报错,但是程序运行的时候就可能会出错。而这样的错误,查找起来又不是很容易。
鉴于此,才这样说:“永远不要把外部函数的原型放到.c文件中”。
那如何才能让编译器检查定义和声明的一致性呢?
前面说,如果把外部函数的原型放到.c文件中,编译器就无法检查声明和定义的一致性(声明和定义不在同一个文件中)。那么,要让编译器检查定义和声明的一致性呢,自然是把定义和声明放在同一个文件中,而如何实现把定义和声明放在同一个文件里呢?
答案:源文件定义的函数,在源文件对应的头文件中声明,然后源文件包含自己的头文件。这样定义和声明就放在同一个文件里了。
最新文章
- linux Ubuntu(Segmentation fault)段错误出现原因及调试方法
- 面试题一 链表中倒数第k个结点
- 李洪强iOS开发之OC[009] -OC无参方法的声明实现和调用
- 【小丸类库系列】Word操作类
- 拦截QT关闭窗口的CloseEvent
- 1 Linux平台下快速搭建FTP服务器 win7下如何建立ftp服务器
- rsync数据同步配置
- poj 3253 Fence Repair(模拟huffman树 + 优先队列)
- POJ- Find a multiple -(抽屉原理)
- spring学习总结二-----面向切面编程(AOP)思想
- 我的python学习笔记一
- jQuery如何停止元素的animate动画,还有怎样判断是否处于动画状态
- 【安富莱】【RL-TCPnet网络教程】第10章 RL-TCPnet网络协议栈移植(FreeRTOS)
- python3 random模块
- [转]laravel DB类SQL语句操作(CURD)
- input修改placeholder文字颜色
- XML与HTML的主要差异
- 商业智能BI-基础理论知识总结 ZT
- Java知多少(27)继承的概念与实现
- sql server2012 远程访问设置(转)
热门文章
- 爬取精美壁纸5w张,爱了爱了
- JZOJ 1082. 【GDOI2005】选址
- Linux:grep 查找文件内容
- webpack的快速使用
- Linux环境安装Go
- [{";morpherRegistry";:{},";dynaClass";:{";dynaProperties";:[{";indexed";:false,";mapp
- ubuntu22.04 git升级
- class和struct区别
- Launchpad是什么?Launchpad使用教程
- JMeter压力测试之环境搭建、脚本调试及报错解决方法(Linux版)