我深知前路风雨,但我依然微笑前行 ;)

头文件相互包含的问题

问题:

头文件交叉包含是否会导致递归包含,导致编译出错?

如果不会因为递归包含出错,那么交叉包含是不是完全没问题?

1.1 头文件交叉包含是否会导致递归包含,导致编译出错?(无#ifndef)

假若头文件a包含了头文件b、头文件b又包含了头文件a,那么在#include头文件a的时候,就可能会导致递归包含,从而导致编译出错;

/* a.h */

#include "b.h"

#define A_H 1

/* b.h */

#include "a.h"

#define B_H 2

/* main.c */

#include

#include

#include "a.h"

#include "b.h"

void main()

{

printf("hello world!\n");

}

在Visual Studio中会提示,头文件包含了自身;编译时会报错:

fatal error C1014: 包含文件太多 : 深度 = 1024

在Ubuntu下面编译会报错:

a.h:1:15: error: #include nested too deeply

b.h:1:15: error: #include nested too deeply

1.2头文件交叉包含是否会导致递归包含,导致编译出错?(有#ifndef)

修改a.h、b.h两个文件,main.c文件内容不变。此时编译正常通过:因此可以知道,当头文件相互包含时,只要有预处理#ifndef就可以保证理论上不会出错。

/* a.h */

#ifdef __A_H_

#define __A_H

#include "b.h"

#define A_H 1

#endif

/* b.h */

#ifndef __B_H_

#define __B_H

#include "a.h"

#define B_H 2

#endif

1.3 如果不会因为递归包含出错,那么交叉包含是不是完全没问题?

从上面的头文件内容可以看出,虽然两个头文件相互包含,但是两个头文件内容并不相互引用。因此编译不会出现问题。但是如果像下面文件,头文件变量又相互引用,则编译会出现变量未知错误

a.h:9:9: error: unknown type name ‘B_H’

/* a.h */

#ifndef __A_H_

#define __A_H_

#include "b.h"

typedef struct _A_H{

int a;

} A_H;

int fun(B_H *ptr);

#endif

/* b.h */

#ifndef __B_H_

#define __B_H_

#include "a.h"

typedef struct _B_H{

A_H b;

} B_H;

#endif

/* main.c */

#include

#include "b.h"

#define CC DD

#define DD 2

void main()

{

printf("hello world!\n");

}

使用 ‘gcc -E main.c > tmp’ 将main.c只做预处理,可以看到预处理后的文件内容为:所以是因为变量定义的顺序问题导致问题。

/* tmp 部分内容*/

# 1 "b.h" 1

# 4 "a.h" 2

typedef struct _A_H{

int a;

} A_H;

int fun(B_H *ptr);

# 4 "b.h" 2

typedef struct _B_H{

A_H b;

} B_H;

# 3 "main.c" 2

int main()

{

printf("hello world!\n");

return 0;

}

1.4 但是将b.h文件中的结构体加上struct又可以编译成功了!!!

此时会出现警告:结构体隐性申明

a.h:9:16: warning: ‘struct _B_H’ declared inside parameter list [enabled by default]

/* a.h */

#ifndef __A_H_

#define __A_H_

#include "b.h"

typedef struct _A_H{

int a;

} A_H;

int fun(struct _B_H *ptr);

#endif

/* b.h */

#ifndef __B_H_

#define __B_H_

#include "a.h"

typedef struct _B_H{

struct _A_H b;

} B_H;

#endif

总结

头文件相互包含,而且变量又相互引用。此时应该将其中一个头文件拆成两个头文件b1.h、b2.h,b1.h让原来的a.h包含;b2.h用来包含a.h。不要使两个头文件变量相互引用引用的设计方式出现。

从上面main.c内容可以看出宏定义的顺序可以不按顺序出现,编译也不会出错。

c语言头文件相互包含的后果,C语言头文件相互包含的问题相关推荐

  1. application.properties引用其他文件_金橙智能 | C语言头文件组织与包含原则,你知道吗?...

    点击蓝字 关注我们 同学们知道C语言中头文件的组织与包含原则吗?如果你还不知道,那么小橙来给你讲解一下,希望同学可以认真学习. 头文件的作用 程序执行在预处理阶段,编译器会把源文件包含的头文件中的内容 ...

  2. c++头文件被c语言调用需要注意什么_嵌入式C语言之模块化编程

    C语言中的模块化体现在两个方面: 1 函数. 函数是C语言的最小单位,每个函数均实现一个独立的功能,于是每个函数均可以当做是一个最小的功能模块.这样,C语言就实现了最基本的模块化. 2 文件. 在C语 ...

  3. html页面包含头文件,Web前端技术:HTML部分---Head标签中包含的头文件标签,body标签包含的内部标签...

    1.Head标签中包含的 头文件标签的作用: (1)title标签:定义网页的标题. (2)meta标签:一般用于定义页面的特殊信息,例如页面的关键字.页面描述等 (3)link标签:用于引入外部样式 ...

  4. C语言程序头文件扩展名为_,c语言程序设计 考试模拟题B.doc

    c语言程序设计 考试模拟题B 题 号 一 二 三 四 五 六 七 八 九 十 成绩 满 分 20 20 30 14 16 100 得 分 [ [本套试卷共有五大题,计29小题] 一.单选题(每小题2分 ...

  5. asp.net使用include包含文件中文乱码_C++: 编写自己的头文件

    C++的多文件结构和预编译命令入门课程,我觉得讲的很好: 学堂在线-国家精品课程在线学习平台​www.xuetangx.com 为在不同的文件中使用同一个类,类的定义就必须保持一致,为确保各个文件中类 ...

  6. c语言中的头文件stdlib.h的作用,C语言头文件#includestdlib.h的作用

    stdlib 头文件即standard library标准库头文件 stdlib 头文件里包含了C.C++语言的最常用的系统函数 该文件包含了的C语言标准库函数的定义 stdlib.h里面定义了五种类 ...

  7. c语言如何编写头文件,如何编写自己的C语言头文件

    一些初学c语言的人,不知道头文件(*.h文件)原来还可以自己写的.只知道调用系统库函数时,要使用#include语句将某些头文件包含进去.其实,头文件跟.c文件一样,是可以自己写的.头文件是一种文本文 ...

  8. 文件处理小程序(包含哈夫曼文件压缩-解压等 C语言)

    文末有源代码 文件压缩.解压.加密(异或加密).解密功能等都实现了,但是处理后文件命名有点不合理,采用了加前缀的方法得到处理后的文件名,应该是改变后缀名. 应该这种更好:test.txt --- &g ...

  9. c语言remove和rename不起作用,C语言探索之旅 | 第二部分第七课:文件读写

    我们学过了这么多变量的知识,已经知道变量实在是很强大的,可以帮助我们实现很多事情. 变量固然强大,还是有缺陷的,最大的缺陷就是: 不能永久保存 . 因为 C语言的变量储存在内存中,在你的程序退出时就被 ...

  10. R 语言怎么保存工作目录到当前路径_C语言探索之旅 | 第二部分第七课:文件读写...

    内容简介 前言 文件的打开和关闭 读写文件的不同方法 在文件中移动 文件的重命名和删除 第二部分第八课预告 1. 前言 上一课 C语言探索之旅 | 第二部分第六课:创建你自己的变量类型 之后,我们来学 ...

最新文章

  1. Linux下C高手成长过程----经典书籍推荐
  2. java集合概念初步介绍
  3. 把数组排列成最小的数(详解)
  4. python dataframe切片_python pandas dataframe 行列选择,切片操作方法
  5. python数字对应车站_python爬虫查询车站信息
  6. dj鲜生-用户中心-历史购物
  7. mysql锁表和解锁语句
  8. STM32工作笔记0040---认识MOS管
  9. 深度学习的最新研究进展(三)
  10. 地理信息革命Geospatial Revolution
  11. 组态王历史记录用access_Access数据库与表在 组态王中使用.ppt
  12. python包的init文件_Python模块包中__init__.py文件的作用
  13. 计算机应用在服务业的发展,饮食服务业计算机应用的现状与未来
  14. directshow方法关键帧java,如何实现DirectShow source filter
  15. matlab 8750h,实测结果表明:九代i7-9750H笔记本标压处理器较8750H提升不大
  16. python节日贺卡图片大全_儿童新年贺卡图片大全
  17. 纺织服装外贸行业解决方案丨汇信外贸软件
  18. java中explain什么意思_Explain关键字解析
  19. MSDC 4.3 接口规范(27)
  20. java计算机毕业设计自动化办公系统源码+mysql数据库+系统+lw文档+部署

热门文章

  1. Halcon教程十四:训练自己的模型然后识别相似的图像
  2. IMX6ULL 的 IEEE 1588 功能
  3. pr22.5最新版下载地址
  4. 有关大学计算机基础考试的试题,大学计算机基础考试试题
  5. 白话区块链 之 14 - ​区块链的技术意义
  6. java正则表达式yyyymmdd_正则表达式校验YYYYMMDD日期格式
  7. HTML5详细介绍及使用
  8. linux i217 v网卡驱动,英特尔网卡驱动下载_Intel英特尔I217I218I219系列网卡驱动官方下载 - 系统之家...
  9. 51单片机-宏晶STC与硬仿真
  10. c语言家庭财务管理算法,c语言家庭财务管理报告.doc