有时候,我们会在项目的头文件中看到如下代码:
[C] 纯文本查看 复制代码 #ifndef XXX
#define XXX
#endif
它的作用就是防止重复包含头文件
举个例子:
以下代码引用了两次test.h
[C] 纯文本查看 复制代码 //test.h
int testFunc()
{
return 114514;
}
//test.c
#include "test.h"
#include "test.h"
int main()
{
}
编译:
[Shell] 纯文本查看 复制代码 gcc test.c -o homo
哦吼,报错了
In file included from .\test.c:3:
.\test.h:1:5: error: redefinition of 'testFunc'
1 | int testFunc()
| ^~~~~~~~
In file included from .\test.c:1:
.\test.h:1:5: note: previous definition of 'testFunc' was here
1 | int testFunc()
| ^~~~~~~~
简单分析一下就知道,是因为有两个个testFunc()
为什么会这样呢?
因为C/C++的引用头文件实际上就是把头文件写入到源文件中,由于引用了两次test.h,所以相当于定义了两侧testFunc
如果添加了最开头的代码呢?
[C] 纯文本查看 复制代码 #ifndef TEST_H
#define TEST_H
int testFunc()
{
return 114514;
}
#endif
第一步,代码会变成这样:
[C] 纯文本查看 复制代码 #define TEST_H
int testFunc()
{
return 114514;
}
后面再次判断时,由于TEST_H已经被定义,所以testFunc不会被定义第二遍
我们用gcc -E查看一下
[Shell] 纯文本查看 复制代码 gcc -E .\test.c > test.i
这是没有使用预编译指令的test.i
[C] 纯文本查看 复制代码 # 1 ".\\test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 ".\\test.c"
# 1 ".\\test.h" 1
int testFunc()
{
return 114514;
}
# 2 ".\\test.c" 2
# 1 ".\\test.h" 1
int testFunc()
{
return 114514;
}
# 4 ".\\test.c" 2
int main()
{
}
可以明显看到testFunc出现了两次
这是使用了预编译指令之后的
[C] 纯文本查看 复制代码 # 1 ".\\test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 ".\\test.c"
# 1 ".\\test.h" 1
int testFunc()
{
return 114514;
}
# 2 ".\\test.c" 2
int main()
{
}
可以看到testFunc只有一次
|