C/C++中.c文件和.h文件的区别

我们在编写一个程序时,往往习惯将程序写为多文件的,这样就能实现程序的模块化管理,以及分工开发合作。而一些全局变量,全局函数,结构体等就能使各模块联系在一起。
在平常写代码的过程中,通常会使用文件包含来联系各代码文件,当然也可能会直接写成多文件程序,没有文件包含,这样也能编译、运行。
下面通过代码来展示一下:

//fun.c
int h = 0;
int cal(int a, int b)
{
    return (2*a+3*b);
}
//main.c
#include "stdio.h"
#include "fun.c"   //包含.c文件
int main(void)
{
    h = 1;   //直接使用fun.c中的变量
    int i = 1,j = 2;
    int c = 0;
    c = cal(i, j);  //直接调用fun.c中的函数
    printf("%d\n", c);
    return 0;
}

在Linux下 编译:gcc main.c -o main 直接编译通过,运行正确。
那么我们再看一个代码

//fun.c
int h = 0;
int cal(int a, int b)
{
    return (2*a+3*b);
}
//fun1.c
#include "fun.c"   // 就这一句
//main.c
#include "stdio.h"
#include "fun.c"   //包含.c文件
#include "fun1.c"   //添加包含fun1.c
int main(void)
{
    h = 1;   //直接使用fun.c中的变量
    int i = 1,j = 2;
    int c = 0;
    c = cal(i, j);  //直接调用fun.c中的函数
    printf("%d\n", c);
    return 0;
}

在Linux下 编译:gcc main.c -o main 编译报错:h cal 发生了重定义。

总结:
优点:可以直接编译main.c文件,不用编译fun.c,因为在main.c的编译预处理阶段,会将fun.c 的代码直接拷贝过来。读者可以使用gcc -E main.c -o main.i 查看预处理后.i文件的代码。发现main.i中将fun.c的代码拷贝了过来。
缺点:fun.c不能被多个文件包含,因为这样就会产生变量和函数的多个拷贝,造成严重的重定义,编译通不过。
这种方式可解决较简单程序的文件包含问题,通常不推荐使用。

如果不使用.h文件直接使用多文件的话:
总结:
优点:不会出现重定义问题
缺点:1、如果要用到的外部变量多,或是在多处要使用外部变量,则要在每一个调用的文件中使用extern声明,比较麻烦。
2、如果是在fun.c中有结构体定义或是类的定义,在main.c中用使用结构体定义变量,或是使用类定义对象。编译不能通过,不知该如何处理。
3、如果是定义在fun.c中的结构体变量,在main.c中要声明外部变量,并使用,会出错。故推知:结构体不能声明为外部变量,只能是包含的头文件中定义的结构体。
解决上述问题的方式就是第三种,包含.h文件方式。

如果包含.h文件
为每一个模块都编写一个.c文件,一个.h文件。
.c源文件中放:函数的定义,全局变量的定义,全局结构体变量的定义。
.h头文件中放:函数的声明,全局变量的声明(extern),全局结构体的定义,全局结构体变量的声明。
调用文件(main.c)文件中:包含.h头文件即可。不用声明任何东西

发布了39 篇原创文章 · 获赞 37 · 访问量 1960

猜你喜欢

转载自blog.csdn.net/weixin_43831728/article/details/103401259
今日推荐