文件包含详解
目录:1.文件包含定义
2.文件包含的处理方法
3.文件包含分类
4.例子
5.两种方法的优缺点
6.说明
1.文件包含定义:文件包含处理是指在一个源文件中,通过文件包含命令将另一个源文件的内容全部包含在此文件中。在源文件编译时,连同被包含进来的文件一同编译,生成目标目标文件。
2.文件包含的处理方法:
1> 处理时间:文件包含也是以"#"开头来写的(#include ), 那么它就是写给预处理器来看了, 也就是说文件包含是会在编译预处理阶段进行处理的。
2>处理方法:在预处理阶段,系统自动对#include命令进行处理,具体做法是:降包含文件的内容复制到包含语句(#include )处,得到新的文件,然后再对这个新的文件进行编译。
3.文件包含分类:包含.h文件、包含.c文件
1>两情况都是按照上面说的方法来处理的。
2>包含.c文件 和编译多文件程序 是不同的。
多文件程序: 是在源文件编译时把多个文件进行编译、连接在一起生成一个可执行文件。
包含.c文件: 按照我们上边的说法则是把多个文件合并为一个文件进行编译。
4.例子
1>包含.c文件:
1: //file1: main.c
2: #include
3: #include "fun.c"
4: int main()
5: {
6: int a=5,b=19;
7: c = a;
8: sun(a,b);
9: printf("c=%d/n",c);
10: return 0;
11: }
12: //end of file1
1: //file2: fun.c
2: int c=0;
3: void sun(int a, int b)
4: {
5: printf("a+b=%d/n",a+b);
6: c=0;
7: printf("c=%d/n",c);
8: }
9: //end of file2
10:
在编译时,直接去编译main.c文件,预处理器会先把fun.c文件中的内容复制到main.c中来,然后再对新的main.c进行编译。
编译命令:
gcc main.c -o main
可以看到,这里并没有对fun.c进行编译,但还是生成了最终的main可执行程序。
也可以通过命令来观察一下预处理的结果:
编译命令:
gcc -E main.c -o main.cpp
在main.cpp文件末尾可以看来下面一段代码:
1: //main.cpp文件中
2: 931 # 2 "main.c" 2
3: 932 # 1 "fun.c" 1
4: 933 //注意这里是fun.c里边的内容
5: 934 int c=0;
6: 935 void sun(int a, int b)
7: 936 {
8: 937 printf("a+b=%d/n",a+b);
9: 938 c=0;
10: 939 printf("c=%d/n",c);
11: 940 }
12: //这里是main函数
13: 941 # 3 "main.c" 2
14: 942 int main()
15: 943 {
16: 944 int a=5,b=19;
17: 945 c = a;
18: 946 printf("c=%d/n",c);
19: 947 sun(a,b);
20: 948 printf("c=%d/n",c);
21: 949 return 0;
22: 950 }
可见,其实就是将fun.c文件中的内容添加到了main函数之前,然后对新的文件进行编译,生成最终的可执行程序。
(2)编译多文件程序:
同样是上边的例子,把main.c中“ #include "fun.c" ”注释掉,加上一句:“extern int c;”因为 c 变量在另外一个文件(fun.c)中定义。
1: //file1: main.c
2: #include
3: //#include "fun.c" //注释掉
4: extern int c; //添加这一句
5: int main()
6: {
7: int a=5,b=19;
8: c = a;
9: sun(a,b);
10: printf("c=%d/n",c);
11: return 0;
12: }
13: //end of file1
14:
15:
16: //file2: fun.c
17: int c=0;
18: void sun(int a, int b)
19: {
20: printf("a+b=%d/n",a+b);
21: c=0;
22: printf("c=%d/n",c);
23: }
24: //end of file2
这次如果还是按照上面的方法只编译main.c的话就会出错,因为变量c和函数sun并没有在main.c中定义,所以编译时需要将fun.c一起编译:
编译命令:
gcc -c main.c -o main.o #编译main.c
gcc -c fun.c -o fun.o #编译fun.c
gcc main.o fun.o -o main #用main.o fun.o生成main
5.两种方法的优缺点
1>包含.c文件的方法: 容易产生"重定义",大家想想如果一个工程中有多个文件都同时包含了某一个件,那么这个被包含文件的内容就会被复制到多个文件中去,也就相当于每个包含该文件的文件中都定义被包含文件中的变量和函数,这样在链接时就会产生"重定义"错误。
2>多文件分开编译的方法: 这个比较好,不容易出现"重定义"之类的问题,这也是我们最常用的一种方法,但是并不是像上面这个例子中这样直接去用,而是使用"头文件"将各个.c文件联系起来。
6.说明
1>包含命令中的文件名可以用双引号括起来,也可以用尖括号括起来。例如以下写法都是允许的:
#include"stdio.h"
#include<math.h>
但是这两种形式是有区别的:使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找;
使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。用户编程时可根据自己文件所在的目录来选择某一种命令形式。
2>一个include命令只能指定一个被包含文件,若有多个文件要包含,则需用多个include命令。
3>文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。
|
|