关于C/C++语言重复包含头文件,编译时报错已定义的宏未定义的原因及解决方法

在编写一个文件较多的单片机程序时,为了在一个文件中定义的变量或宏能被另一个文件使用,经常会写成在多个头文件相互包含,由此将可能会导致明明已经定义的宏,且已经将宏所在的文件使用 #include  包含,编译时仍会报错未定义。

先来看一段简单的代码

main.c

#include "main.h"

void SystemInit(void)
{

}

int main(void)
{

}

main.h

#ifndef __MAIN_H_
#define __MAIN_H_





#endif

lk.c

#include "lk.h"


unsigned char Admin_num;

lk.h

#ifndef __LK_H_
#define __LK_H_

#include "head.h"


#define MAX_LEN (32)
#define KEY_LEN (32)


#endif

fp.c

#include "fp.h"




FP_TypeDef User_Data;

fp.h

#ifndef __FP_H_
#define __FP_H_

#include "head.h"


typedef struct
{
	unsigned char id;
	unsigned char key[MAX_LEN];

}FP_TypeDef;



#endif



head.h 

#ifndef __HEAD_H_
#define __HEAD_H_

#include "fp.h"
#include "lk.h"


#endif

此时编译将会报错 ,提示在fp.h文件中 MAX_LEN  没有定义

 

 我们单个C文件编译,发现,fp.c能通过, lk.c 文件居然报错

lk.c 看上去并没有什么错误为什么会报错呢,而且fp.h文件中用到的  MAX_LEN  已经通过head.h文件将 lk.h文件包含进入,MAX_LEN 是在lk.h文件中定义的,为什么还会提示在fp.h文件中未定义MAX_LEN  ??

原因分析

我们将 lk.c 中所有的 #include  全部用对应的头文件层层替换,得到的代码为:

 1、lk.c原文

#include "lk.h"


unsigned char Admin_num;

 2、用lk.h 中的内容替换 #include "lk.h"

//#ifndef __LK_H_   //前面没有定义过__LK_H_,所以编译 #ifndef 到 #endif 的内容
#define __LK_H_

#include "head.h"


#define MAX_LEN (32)
#define KEY_LEN (32)


//#endif


unsigned char Admin_num;

 3、用head.h 中的内容替换 #include "head.h" 

//#ifndef __LK_H_   //前面没有定义过 __LK_H_,所以编译 #ifndef 到 #endif 的内容
#define __LK_H_

//#ifndef __HEAD_H_	//前面没有定义过 __HEAD_H_,所以编译 #ifndef 到 #endif 的内容
#define __HEAD_H_

#include "fp.h"
#include "lk.h"


//#endif


#define MAX_LEN (32)
#define KEY_LEN (32)


//#endif


unsigned char Admin_num;

 4、用fp.h 中的内容替换 #include "fp.h" 

//#ifndef __LK_H_   //前面没有定义过 __LK_H_,所以编译 #ifndef 到 #endif 的内容
#define __LK_H_

//#ifndef __HEAD_H_	 //前面没有定义过 __HEAD_H_,所以编译 #ifndef 到 #endif 的内容
#define __HEAD_H_


//#ifndef __FP_H_   //前面没有定义过 __FP_H_,所以编译 #ifndef 到 #endif 的内容
#define __FP_H_

#include "head.h"


typedef struct
{
	unsigned char id;
	unsigned char key[MAX_LEN];

}FP_TypeDef;



//#endif



#include "lk.h"


//#endif


#define MAX_LEN (32)
#define KEY_LEN (32)


//#endif


unsigned char Admin_num;

 5、用head.h 中的内容替换 #include "head.h" 

//#ifndef __LK_H_   //前面没有定义过 __LK_H_,所以编译 #ifndef 到 #endif 的内容
#define __LK_H_

//#ifndef __HEAD_H_	 //前面没有定义过 __HEAD_H_,所以编译 #ifndef 到 #endif 的内容
#define __HEAD_H_


//#ifndef __FP_H_   //前面没有定义过 __FP_H_,所以编译 #ifndef 到 #endif 的内容
#define __FP_H_

//#ifndef __HEAD_H_   //前面已经定义过 __HEAD_H_,所以不再编译 #ifndef 到 #endif 的内容
/*#define __HEAD_H_

#include "fp.h"
#include "lk.h"
*/

//#endif




typedef struct
{
	unsigned char id;
	unsigned char key[MAX_LEN];

}FP_TypeDef;



//#endif



#include "lk.h"


//#endif


#define MAX_LEN (32)
#define KEY_LEN (32)


//#endif


unsigned char Admin_num;

 6、用lk.h 中的内容替换 #include "lk.h"

//#ifndef __LK_H_   //前面没有定义过 __LK_H_,所以编译 #ifndef 到 #endif 的内容
#define __LK_H_

//#ifndef __HEAD_H_	 //前面没有定义过 __HEAD_H_,所以编译 #ifndef 到 #endif 的内容
#define __HEAD_H_


//#ifndef __FP_H_   //前面没有定义过 __FP_H_,所以编译 #ifndef 到 #endif 的内容
#define __FP_H_

//#ifndef __HEAD_H_   //前面已经定义过 __HEAD_H_,所以不再编译 #ifndef 到 #endif 的内容
/*#define __HEAD_H_

#include "fp.h"
#include "lk.h"
*/

//#endif




typedef struct
{
	unsigned char id;
	unsigned char key[MAX_LEN];

}FP_TypeDef;



//#endif



//#ifndef __LK_H_  //前面已经定义过 __LK_H_,所以不再编译 #ifndef 到 #endif 的内容
/*#define __LK_H_

#include "head.h"


#define MAX_LEN (32)
#define KEY_LEN (32)
*/

//#endif


//#endif


#define MAX_LEN (32)
#define KEY_LEN (32)


//#endif


unsigned char Admin_num;

7、去掉所有注释,lk.c中最终的内容为:


#define __LK_H_
#define __HEAD_H_
#define __FP_H_


typedef struct
{
	unsigned char id;
	unsigned char key[MAX_LEN];

}FP_TypeDef;



#define MAX_LEN (32)
#define KEY_LEN (32)


unsigned char Admin_num;

可以发现, 结构体中用到的  MAX_LEN   在前面并没有定义,而是在后面定义的,最终导致编译错误。

重复包含头文件,会使后面定义的内容,被前面的条件编译忽略,导致不被编译。

解决方法

将 #include  语句放在所有宏定义之后

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>