本文可解决的问题:

  1. 在一个头文件.h中定义一个结构体,在另一个.h文件中使用这个结构体引发错误
  2. C2143    语法错误: 缺少“)”(在“*”的前面) (编译源文件......等莫名的报错
  3. 头文件的交叉包含,即头文件a包含了头文件b、头文件b又包含了头文件a
  4. 多个不同的头文件包含同一个头文件,导致重复包含和预编译

解决方案:

1,防止头文件重复包含和交叉包含导致的问题

//防止头文件重复包含和交叉包含导致的问题
//只需要增加如下代码段在头文件开头
//第一次包含了该头文件后,就已经#define 了一次_COM_UTIL_H_,第二次包含时会遇到“#ifndef _COM_UTIL_H_”的判断,
//既然已经定义,条件不成立,后面的不再执行,头文件就不会再加进去
//这里的头文件为com_util.h#ifndef _COM_UTIL_H_
#define _COM_UTIL_H_//这里是com_util.h的内容
#endif

2, 头文件中的变量存在相互引用,或者两个头文件在包含时顺序不对的话,会出现识别不了已定义变量,结构体,类的情况.

****************************现在有两个头文件
-------------------head1.h文件内容
#ifndef __HEAD_1_H__
#define __HEAD_1_H__#include "head2.h"           #define VAR_MACRO    1          ///这里define a macro, which used in head2.hbool func(ClassA* CA);        ///ClassA is defined in head2.h#endif-------------------head2.h文件内容
#ifndef __HEAD_2_H__
#define __HEAD_2_H__#include "head1.h"class ClassA{int mVar;void setMem(){ mVar = VAR_MACRO };    //macro VAR_MACRO is defined in head1.h...     //other members and functions
};#endif

现在另有两个源文件
---------------------source1.cpp----------------------
#include "head1.h"
int main(){
//... some source codereturn 0;
}---------------------source2.cpp---------------------
#include "head2.h"
int main(){
//... some source codereturn 0;
}

上述代码编译完之后会报错,大致意思是 ClassA 和 VAR_MACRO 没有定义.

对于 source1.cpp,它包含了头文件 head1.h,那么在编译之前,在 source1.cpp 中展开 head1.h,而 head1.h 又包含了 head2.h, 那么也展开它,这时 source1.cpp 就变成类似下面这样:

 ------------------source1.cpp 的展开
//注意这句#include "head1.h",由于#ifndef __HEAD_1_H__的存在,而不会再包含
class ClassA{int mVar;void setMem(){ mVar = VAR_MACRO };    //macro VAR_MACRO is defined in head1.h...     //other members and functions
};#define VAR_MACRO  1          //define a macro, which used in head2.hbool func(ClassA* CA);        //ClassA is defined in head2.hint main(){
//... some source codereturn 0;
}===========================================================================================
source1.cpp 会出现 VAR_MACRO 的定义的错误,因为VAR_MACRO 的使用在定义之前.

同理展开source2.cpp:

------------------- source2.cpp 的展开:#define VAR_MACRO  1          //define a macro, which used in head2.hbool func(ClassA* CA);        //ClassA is defined in head2.hclass ClassA{int mVar;void setMem(){ mVar = VAR_MACRO };    //macro VAR_MACRO is defined in head1.h...     //other members and functions
};int main(){
//... some source codereturn 0;
}===========================================================================================
func 函数声明之前并没有发现 ClassA 类型定义,该定义在函数声明的后面,这时候如果能在head1.h 的
函数声明之前加上 ClassA CA; 的前置声明,就不会在编译的时候报找不到 ClassA 的定义的错误了。

3,修改方法:调整代码甚至.h文件的顺序

****************************修改后的两个头文件
-------------------head1.h修改:将VAR_MACRO宏定义放在#include "head2.h" 前
#ifndef __HEAD_1_H__
#define __HEAD_1_H__#define VAR_MACRO    1          ///这里define a macro, which used in head2.h
#include "head2.h"           //ClassA CA;                  ///也可以直接在这里作ClassA CA前置声明,则head2.h不用再做下面的修改,可保持原状
bool func(ClassA* CA);        ///ClassA is defined in head2.h#endif-------------------head2.h修改:在#include "head1.h"前,添加预声明 ClassA CA;
#ifndef __HEAD_2_H__
#define __HEAD_2_H__ClassA CA;               ///如果head1.h添加了预定义,这条语句可以删除,建议这里删除
#include "head1.h"class ClassA{int mVar;void setMem(){ mVar = VAR_MACRO };    //macro VAR_MACRO is defined in head1.h...     //other members and functions
};#endif

4,注意结构体和类,可以在定义前进行预声明 :

注意,不是所有的.h文件都要放在文件开头,要注意调整#include *.h文件的顺序和位置,

例如在com_def.h文件中,把大部分.h文件放在该文件的最后:

部分参考:


https://blog.csdn.net/hazir/article/details/38600419文章给出了非常好的解释.感谢作者的贡献.

https://blog.csdn.net/zyz394515661/article/details/83218462文章亦可作为参考.


C语言头文件.h互相包含所引发的一系列错误C2143之类的解决方法相关推荐

  1. C语言头文件避免重复包含

    C语言头文件避免重复包含 假定有以下几个头文件及其包含关系为: File1.h,file2.h,file3.h,file4.h,file5.h,main.cpp 那么:file3.h包含file1.h ...

  2. c语言头文件命名规则,C语言头文件规则.doc

    C语言头文件规则.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3.该文档所得收 ...

  3. c语言头文件包含嵌套问题和包含原则

    a.h #include<stdio.h> #ifndef _A_H #define _A_H 只是解决头文件重复包含的问题的,但是头文件嵌套包含,就不代表不会出问题,就会关系错综复杂,出 ...

  4. C语言头文件互锁和包含问题

    正文 大家好,我是bug菌! 今天带来的主要内容是关于头文件的那些事,或许头文件并不是那么起眼,大部分人在编程中对头文件的组织并没有形成一定的设计思路,虽然使用了一些预编译在一定程度上能够减少重复包含 ...

  5. C语言头文件为什么要加#ifndef #define #endif(防止头文件重复包含)

    当你用VC的菜单新增一个类,你会发现自动生成的代码总是类似下面的样子: #if !defined(AFX_XXXX__INCLUDED_)#define AFX_XXXX__INCLUDED_具体代码 ...

  6. c语言头文件中定义inline static相关函数的优劣

    头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-none-eabi-gcc下测试后得出结论. in ...

  7. extern与头文件(*.h)的区别和联系

    原文网址为:http://lpy999.blog.163.com/blog/static/117372061201182051413310/ 个人认为有一些道理:所以转过来学习了. 用#include ...

  8. ifndef/define/endif——主要目的是防止头文件的重复包含和编译

    原文:http://www.jb51.net/article/100939.htm 原文:https://blog.csdn.net/abc5382334/article/details/180527 ...

  9. c语言程序头文件作用,C语言头文件

    C语言头文件教程 C 语言的头文件一般都是 .h 做为结尾的. C语言头文件详解 语法 #include 参数 参数 描述 filename 我们需要引入的头文件的名称. 说明 C 语言的头文件一般都 ...

最新文章

  1. usaco ★Stamps 邮票
  2. bulma.css_如何建立一个? 具有Bulma CSS的特斯拉响应页面
  3. paddle版fnet_google
  4. StringBuilder类型的基本用法
  5. C# 程序员最常犯的 10 个错误
  6. pytorch 1.9.0 backward函数解释以及报错(RuntimeError: grad can be implicitly created only for scalar outputs)
  7. php 我已阅读并同意 判断,phb.php
  8. mongodb 数字 _id_MongoDB学习笔记MongoDB简介及数据类型
  9. c++基础语句(条件判断)
  10. sql中截取字符串函数_SQL Server 2017中的顶级SQL字符串函数
  11. ps html插件初始化失败,解决PSCC2019无法安装扩展插件怎么办?
  12. C++ DNF脚本源码模板开源
  13. 南航计算机学院物联网,南航*物联网
  14. php图片64位处理,php实现图片以base64显示的方法
  15. Android系统WebView无法安装,Android系统进程无法加载WebView
  16. 如何使用爬虫与JieBa库制作词云
  17. 【MM32F5270开发板试用】六、如何用 星辰内核 + 国产RTOS 通过I2S播放 “星辰大海”
  18. JAVA 操作excel的问题,待高手解决。。。
  19. VMware vSphere6.0 服务器虚拟化部署安装图解(转载火星小编)
  20. 100集华为HCIE安全培训视频教材整理 | 安全策略

热门文章

  1. 腾讯收购Foxmail的意图
  2. Ngnix:防止恶意域名解析
  3. Python3.6-Flask:制作一个语音对话问答机器人系统(网页版)
  4. Java Service Wrapper将java程序设置为服务
  5. ubuntu下载神器---xdm
  6. 币圈炒币如何避免被额韭菜?
  7. 无线传感器网络中的节点定位技术
  8. 怎样提高工作积极性与工作效率
  9. html网页模板中文乱码,Flash中出现中文乱码的解决办法
  10. 医保卡和社保卡的区别