#ifndef #define #endif防止的是“重复编译”,而不是“重复定义”

#ifndef #define #endif防止的是“重复编译”,而不是“重复定义”
重复编译可能造成重复定义,但重复定义的来源不只有重复编译

从代码变成可执行的程序,需要两个步骤
编译和链接
编译开始时,将所有#include头文件的地方替换成该头文件的代码
在编译阶段,编译所有源文件成为模块,各模块中的每个变量与函数都得到了属于自己的空间
在链接阶段,各个模块被组合到一起

#ifndef能够防止在编译阶段,一段代码被重复编译,并且由此可以避免一个变量被重复定义
但它不能防止链接阶段,各模块中都有叫某个名字的变量,于是报链接错误:变量重复定义

解决方法就如1楼所说,不仅用#ifndef组合防止重复编译,而且将变量在源文件中定义,只在头文件里放extern声明
这样各模块在编译的时候,就知道“有这么个变量,但它的空间不在我这里”,链接的时候,这个变量虽然出现在所有包含这个头文件的模块里,但只有一个模块是它的真身所在
### #ifndef#define#endif 的作用及防止头文件重复包含的使用方法 #### ### 1. #ifndef#define#endif 的基本功能 `#ifndef`、`#define` 和 `#endif` 是C/C++中的预处理指令,用于条件编译。它们的主要作用是防止头文件被多次包含,从而避免重复定义编译错误[^2]。 - **#ifndef**:检查某个宏是否未定义。如果该宏未定义,则执行其后的代码块。 - **#define**:定义一个宏,通常用于标记头文件已被包含。 - **#endif**:结束由 `#ifndef` 开始的条件编译块。 #### ### 2. 防止头文件重复包含的机制 在C/C++中,头文件可能会被多个源文件包含,或者在一个源文件中被多次包含。为了避免重复定义的问题,通常会在头文件中使用 `#ifndef`、`#define` 和 `#endif` 的组合来保护头文件内容[^3]。 例如,以下是一个典型的头文件保护机制: ```c #ifndef HEADER1_H #define HEADER1_H // 头文件的内容 int add(int a, int b); #endif // HEADER1_H ``` 在这个例子中,`HEADER1_H` 是一个宏名,通常由头文件名转换而来(将头文件名大写,并用下划线替换点号)。如果 `HEADER1_H` 尚未定义,则定义它并包含头文件的内容;否则跳过头文件的内容,从而避免重复定义。 #### ### 3. 示例代码 以下是一个完整的示例,展示如何使用 `#ifndef`、`#define` 和 `#endif` 来保护头文件。 **头文件 `add.h`** ```c #ifndef ADD_H #define ADD_H int add(int a, int b); #endif // ADD_H ``` **实现文件 `add.cpp`** ```c #include "add.h" int add(int a, int b) { return a + b; } ``` **主程序 `main.cpp`** ```c #include <iostream> #include "add.h" int main() { int result = add(5, 7); std::cout << result << std::endl; return 0; } ``` 在这个例子中,`add.h` 使用了 `#ifndef`、`#define` 和 `#endif` 来确保即使 `add.h` 被多次包含,函数声明 `int add(int a, int b);` 也只会被处理一次[^2]。 #### ### 4. 宏名的命名规范 宏名通常遵循一定的命名规范,以减少冲突的可能性。常见的命名方式是将头文件名转换为大写形式,并用下划线替换点号和其他特殊字符[^1]。例如,对于头文件 `example.h`,宏名可以命名为 `_EXAMPLE_H_`。 #### ### 5. 其他相关指令 除了 `#ifndef`,还可以使用 `#ifdef` 和 `#if` 等指令进行条件编译。例如: ```c #ifdef DEBUG // 调试代码 #else // 非调试代码 #endif ``` 这段代码根据是否定义了 `DEBUG` 宏来选择性地编译不同的代码块[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值