首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

谈谈 include

2024-12-16 来源:化拓教育网

我们知道C的整个编译过程由预处理,编译,链接三个步骤组成。include命令是在预处理阶段解析的。而
预处理阶段只是进行简单的文本替换
我们先来看看一个简单的预处理过程
main.c

int main()
{
#if 1
        int a=1;
        int b=2;
        int sum = a + b;
#endif
        return (1+2);
}

对main.c文件进行预处理 gcc -E main.c -o main.i

# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"


int main()
{
                                               //对应 main.c 文件此行应该是 #if 1,现在已用空行 替换
        int a=1;
        int b=2;
        int sum = a + b;
                                             //对应 main.c 文件此行应该是 #endif 现在已用空行替换
        return (1+2);
}

我们对main.c文件稍加改动
main.c

int main()
{
#if 0                        //!!!!!!!!!!!
        int a=1;
        int b=2;
        int sum = a + b;
#endif
        return (1+2);
}

我们利用if宏使得三行代码无效,我们再来看看预处理的结果

# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"


int main()
{
                                          //我们可以看到,预处理只是将这段无效代码用空行替换




        return (1+2);
}

其实,预处理阶段只是进行简单的文本替换

一般情况下我们通过头文件来定义外部接口,然后通过include宏来引用。这里我们有一个例子
add.h

int notice
#ifndef ADD_H__
#define ADD_H__

int add(int a,int b);

int  test = 100;         

#endif

add.c


int add(int a,int b)
{
    return (a+b);
}

main.c

#include "add.h"

int main()
{
    return add(1,1);
}

对main.c文件进行预处理 gcc -E main.c -o main.i
main.i

# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 1 "add.h" 1
int notice;                  //头文件add.h里面的内容
                                //ifndef等宏命令,现在已经以空行替换



int add(int a,int b); 

int test = 100;     
# 2 "main.c" 2

int main()
{
        return add(1,2);
}

我们可以看到我们通过include引入了add.h里面的内容到main.c
头文件里有下面几行

#ifndef  ...
#define  ...
.....
#endif

是用来防止头文件重复包含的
现在我们再来看一下

main.c

#include "add.h"
#include "add.h"

int main()
{
  

预处理后的结果
main.i

# 1 "main.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 1 "add.h" 1
int notice;                 //头文件add.h里面的内容
                                //ifndef等宏命令,现在已经以空行替换



int add(int a,int b);

int test = 100;
# 2 "main.c" 2
# 1 "add.h" 1
int notice;  //此处在ifndef等宏命令之前,所以被复制过来了,我们可以看到,因为此时ADD_H__已经被定义,所以内容以空替换
# 3 "main.c" 2

int main()
{
        return add(1,2);
}

另外我们可以发现,notice变量被重定义了。

所以include命令会无条件的引入文本文件,但是我们可以通过

#ifndef  ...
#define  ...
.....
#endif

方法防止文件里面的内容被重新包含(复制)。

预处理阶段只是进行简单的文本替换,而有了这几种宏命令,我们便可以更灵活的设置文件的包含过程。

预处理阶段只是进行简单的文本替换 其实不完全对,但是对于我们理解一些简单的宏命令是足够的。

显示全文