论C/C++的条件编译#if、#ifdef、#ifndef、#undef

我们以实例来演示:
------------------------------------------实验①------------------------------------------
子函数:
在这里插入图片描述
主函数:
在这里插入图片描述
当定义了COMMENT_FLAG该宏,且其为0,则运行结果如下:只执行了sub_func_1函数。
在这里插入图片描述

------------------------------------------实验②------------------------------------------
子函数:
在这里插入图片描述
主函数:
在这里插入图片描述
当定义了COMMENT_FLAG该宏,且其为1,则运行结果如下:执行了sub_func_0、sub_func_1函数。
在这里插入图片描述
实验结论:
对于#if,宏COMMENT_FLAG被定义为1,则其条件编译有效;宏COMMENT_FLAG被定义为0,则其条件编译无效。其效果类似于 if 行为。
对于#ifdef,只要定义了宏COMMENT_FLAG,无论其是被定义为1或0,都可执行其条件编译内容。
至于#ifndef的作用,与#ifdef是相反的,宏COMMENT_FLAG只要没有被定义,则执行#ifndef的条件编译。

还有一个#undef,可以在定义COMMENT_FLAG该宏后,取消其定义。简单做个实验:
在这里插入图片描述

在第48行,使用了 #undef COMMENT_FLAG,无任何运行结果,即sub_func_0、sub_func_1函数都没有被执行。

在这里插入图片描述

<think> 我们正在讨论C/C++中的预处理指令,特别是#ifndef、#define、#include、#ifdef和#endif。这些指令在头文件保护和条件编译中扮演重要角色。根据引用内容,我们可以总结如下: 1. #include:用于包含头文件,将指定文件的内容插入到该指令所在的位置。 2. #define:用于定义宏,可以是常量、函数宏或标识符。 3. #ifndef:如果指定的宏没有被定义,则编译其后的代码,直到遇到#endif。 4. #ifdef:如果指定的宏已经定义,则编译其后的代码,直到遇到#endif。 5. #endif:结束条件编译块。 其中,头文件保护(防止重复包含)的典型结构是: ```cpp #ifndef HEADER_NAME_H #define HEADER_NAME_H // 头文件内容 #endif ``` 当同一个头文件被多次包含时,第一次包含会定义宏,后续包含会因为#ifndef条件不成立而跳过内容,避免重复定义。 另外,条件编译允许根据不同的条件编译不同的代码段,常用于跨平台或调试。 现在,根据用户的问题,我将详细解释这些指令的作用和用法,并参考引用内容。 </think> 在 C/C++ 中,预处理指令是编译器在正式编译前处理的命令,主要用于条件编译和文件包含。以下是对关键指令的详细说明: ### 1. `#include` - 文件包含 **作用**:将指定文件的内容插入到当前位置 **用法**: ```cpp #include <iostream> // 包含标准库头文件 #include "myheader.h" // 包含自定义头文件 ``` - 尖括号 `<>` 用于标准库,双引号 `""` 用于用户自定义文件 - 可能引发重复包含问题(需配合 `#ifndef` 解决) ### 2. `#define` - 宏定义 **作用**:定义宏或常量 **用法**: ```cpp #define PI 3.14 // 定义常量 #define MAX(a,b) ((a)>(b)?(a):(b)) // 定义函数宏 ``` - 宏在预处理阶段进行文本替换 - 常量宏通常全大写以示区别 ### 3. `#ifndef` 与 `#endif` - 头文件保护 **作用**:防止头文件被重复包含 **典型结构**: ```cpp // myheader.h #ifndef MYHEADER_H // 如果未定义 MYHEADER_H #define MYHEADER_H // 则定义该宏 // 头文件实际内容 class MyClass { public: void doSomething(); }; #endif // MYHEADER_H // 结束条件编译 ``` **工作原理**[^1]: 1. 首次包含时 `MYHEADER_H` 未定义,执行 `#ifndef` 后的代码 2. 后续包含时因宏已定义,跳过整个代码块 3. `#endif` 标记条件编译块的结束 ### 4. `#ifdef` - 条件编译 **作用**:检查宏是否已定义,用于平台适配或调试 **用法**: ```cpp #ifdef DEBUG std::cout << "Debug mode enabled"; // 仅当 DEBUG 定义时编译 #endif ``` **常见场景**: - 跨平台代码:`#ifdef _WIN32` / `#ifdef __linux__` - 功能开关:`#ifdef USE_FEATURE_X` ### 5. 完整指令清单 | 指令 | 作用 | |------------|-------------------------------| | `#if` | 表达式为真时编译代码 | | `#elif` | 等效于 `#else` + `#if` | | `#undef` | 取消已定义的宏 | | `#error` | 强制编译错误并输出消息 | ### 示例解析 ```cpp #ifndef SALES_DATA_H #define SALES_DATA_H #include <string> struct Sales_data { std::string bookNo; unsigned units_sold = 0; double revenue = 0.00; }; #endif ``` 此结构确保 `Sales_data` 声明仅被包含一次[^4],避免重复定义错误。 > **关键点总结** > - `#ifndef`/`#endif` 是头文件保护的**黄金标准** > - `#define` 在保护结构中用于**标记已包含状态** > - `#ifdef` 多用于**运行时配置**而非头文件保护 > - 所有条件编译指令必须**严格配对**(如 `#ifdef` 必须对应 `#endif`)[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值