C语言多文件编程

要点:

        头文件尽量只有声明,不要有定义,即使使用了header guide #ifndef...#define...#endif。

       #ifndef.....#define.....#endif可以避免编译时的重复定义,但是无法避免多个文件链接时的重复定义。 

        头文件应该尽量少的include其他头文件。

1、a包含b

//a.c文件
#include"c.h"
#include

int main(){
	func();
	printf("i=%d",i);
}

//b.c文件
#include
int i = 5;
int func(){
	printf("hello world\n");
}

//c.h文件
#include
extern int i;
int func();

使用MinGW的gcc编译:gcc a.c b.c,得到a.exe,执行输出

hello world
i=5

分析:

1、以上例子中,源文件b.c和头文件c.h名字不一样(一个b一个c),是没有关系的,但是不推荐这么做。

2、stdio.h看上去被include了两次,其内部必然经过了处理,怎么处理的,文章下面详细介绍。

2、a包含b和c,b包含c,c被重复包含

//a.c文件
#include"c.h"
#include"b.h"
#include

int main(){
	func_b();
	func_c();
	printf("i=%d",i);
}

//b.c文件
#include"c.h"
#include

int func_b(){
	func_c();
}

//b.h文件
#include"c.h"
#include

int func_b();

//c.c文件
#include
int i = 5;
int func_c(){
	printf("hello world\n");
}

//c.h文件
#include
extern int i;
int func_c();

使用MinGW的gcc编译:gcc a.c b.c c.c,得到a.exe,执行输出

hello world

hello world
i=5

分析:

1、以上例子中,c.h看上去被include了两次,为什么没有报错?==>这是因为c.h中只声明了变量i和函数func_c(),并没有定义,声明是可以多次存在的,定义有且只有一次。

修改一下:

//c.c文件
#include
int func_c(){
	printf("hello world\n");
}

//c.h文件
#include
int i = 5;
int func_c();

使用MinGW的gcc编译:gcc a.c b.c c.c,会报错,变量i被重复定义了:

 D:\MinGW\test>gcc a.c b.c c.c
In file included from b.h:1:0,
                 from a.c:2:
c.h:2:5: error: redefinition of 'i'
 int i = 5;
     ^
In file included from a.c:1:0:
c.h:2:5: note: previous definition of 'i' was here
 int i = 5;
     ^

继续修改代码:

#include
#ifndef __C_H  
#define __C_H  
int i = 5;
int func_c();
#endif

使用MinGW的gcc编译:gcc a.c b.c c.c,会报错,变量i还是被重复定义了:

D:\MinGW\test>gcc a.c b.c c.c
C:\Users\Administrator\AppData\Local\Temp\ccoVNTls.o:b.c:(.data+0x0): multiple definition of `i'
C:\Users\Administrator\AppData\Local\Temp\ccBVK4Eh.o:a.c:(.data+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

但是,这里的重复定义发生的阶段确实不同的,上一个例子中重复定义发生在编译(compile)的时候,而这个例子中的重复定义则发生在链接(Link)的时候,因为编译的时候是每个源文件独立进行的,都会将变量i定义进去且分配内存空间,由此产生的不同的目标文件在链接的时候就会发生重复定义。

C语言多文件编程_第1张图片

所以,即使使用的条件编译#ifndef,如果在头文件中定义变量仍有可能发生重复定义,所以一定要避免在头文件中定义变量!

参考

C语言模块化开发,深入多文件编程

你可能感兴趣的:(C,c语言,多文件编程,extern,头文件)