#ifdef与#ifndef的区别到底有多大?一文看懂条件编译底层机制

嵌入式C语言-预编译命令(#define、#if、#ifdef、#ifndef、#undef) 本篇文章详细介绍了C语言中预编译命令 阅读详情

第一章:#ifdef与#ifndef的本质解析

`#ifdef` 和 `#ifndef` 是 C/C++ 预处理器指令,用于条件编译。它们根据宏是否已定义来决定是否包含某段代码,是实现跨平台兼容、调试开关和模块化配置的关键工具。

预处理阶段的作用机制

在编译开始前,预处理器会扫描源文件并处理所有以 `#` 开头的指令。`#ifdef` 检查指定宏是否已被 `#define` 定义;若存在,则其后的代码块被保留。相反,`#ifndef` 判断宏是否未定义,常用于防止头文件重复包含。

#ifndef MY_HEADER_H
#define MY_HEADER_H

// 头文件内容
struct Data {
    int value;
};

#endif // MY_HEADER_H
上述代码确保 `MY_HEADER_H` 仅被定义一次,避免重复声明引发的编译错误。

#ifdef 的典型应用场景

  • 启用调试输出:通过定义 DEBUG 宏控制日志打印
  • 平台适配:针对不同操作系统选择对应实现
  • 功能开关:按需编译特定模块以减小二进制体积
例如:

#ifdef DEBUG
    printf("Debug: current value = %d\n", x);
#endif
当使用 `-DDEBUG` 编译时(如 `gcc -DDEBUG main.c`),调试语句生效;否则被自动剔除。

与 #if defined 的等价性

`#ifdef MACRO` 等价于 `#if defined(MACRO)`,后者支持更复杂的逻辑组合:

#if defined(DEBUG) && defined(ENABLE_LOGGING)
    log_message("Detailed trace enabled.");
#endif
该特性允许同时判断多个宏的存在状态,提升条件编译的表达能力。
指令作用典型用途
#ifdef若宏已定义则编译后续代码启用功能模块
#ifndef若宏未定义则编译后续代码防止头文件重复包含

第二章:条件编译的核心机制

2.1 #ifdef 的工作原理与宏定义检查

预处理器指令的执行时机
#ifdef 是C/C++预处理器提供的条件编译指令,用于在编译前检查某个宏是否已被定义。它不参与运行时逻辑,而是在源码编译初期由预处理器解析。
基本语法与使用示例

#ifdef DEBUG
    printf("调试模式已启用\n");
#endif

#ifndef MAX_SIZE
    #define MAX_SIZE 1024
#endif
上述代码中,#ifdef DEBUG 判断宏 DEBUG 是否存在,若存在则保留打印语句;#ifndef MAX_SIZE 检查宏未定义时才进行定义,常用于防止重复定义。
嵌套与逻辑组合
  • #ifdef 可与 #else、#elif 结合实现多条件分支
  • 支持通过 defined(MACRO) 在 #if 中进行更复杂的逻辑判断

2.2 #ifndef 的作用域与防重包含策略

在C/C++项目中,头文件可能被多个源文件间接包含,导致重复定义错误。#ifndef、#define 和 #endif 构成的“头文件守卫”是防止重复包含的核心机制。
头文件守卫的基本结构
#ifndef MY_HEADER_H
#define MY_HEADER_H

// 头文件内容
typedef struct {
    int id;
    char name[32];
} User;

#endif // MY_HEADER_H
上述代码中,首次包含时 MY_HEADER_H 未定义,预处理器会定义该宏并包含内容;后续再次包含时,因宏已定义,中间内容将被跳过,从而避免重复声明。
宏命名规范与作用域
为确保唯一性,宏名通常采用全大写、以下划线分隔的格式,并结合项目名与文件路径,例如:#ifndef PROJECT_MODULE_CONFIG_H。若宏名冲突,会导致错误屏蔽,因此命名需谨慎。
  • 宏的作用域从定义处开始,直至文件结束或被 #undef 显式取消;
  • 不同头文件使用相同守卫宏将导致相互屏蔽,应避免。

2.3 预处理器如何解析条件编译指令

预处理器在编译的第一阶段处理条件编译指令,根据宏定义的状态决定哪些代码被保留并传递给编译器。
常见条件编译指令
#ifdef DEBUG
    printf("调试模式开启\n");
#endif

#ifndef MAX_SIZE
    #define MAX_SIZE 1024
#endif

#if defined(PLATFORM_LINUX) && !defined(NO_THREADS)
    #include <pthread.h>
#endif
上述代码展示了 #ifdef、#ifndef 和 #if defined(...) 的典型用法。预处理器会先展开宏,再评估逻辑表达式,仅将为“真”的分支保留在输出中。
解析流程
  • 扫描源文件中的 #if、#elif、#else、#endif 指令
  • 计算条件表达式:支持常量表达式与宏替换
  • 跳过不满足条件的代码块,不进行词法分析
流程图:源码 → 预处理器扫描 → 条件求值 → 保留有效代码 → 输出到编译器

2.4 头文件保护中的 #ifndef 实践案例

在C/C++项目中,头文件重复包含会导致编译错误。使用 #ifndef 宏定义是防止此类问题的经典手段。
基本语法结构
#ifndef HEADER_NAME_H
#define HEADER_NAME_H

// 头文件内容

#endif // HEADER_NAME_H
该结构通过预处理器判断是否已定义宏 HEADER_NAME_H。若未定义,则包含内容并定义该宏,防止后续重复处理。
实际应用场景
假设创建一个数学工具头文件 math_utils.h:
#ifndef MATH_UTILS_H
#define MATH_UTILS_H

double add(double a, double b);
int factorial(int n);

#endif // MATH_UTILS_H
即使该头文件被多个源文件或同一文件多次包含,宏保护确保内容仅被编译一次,避免重复声明错误。

2.5 多层嵌套条件编译的执行逻辑

在复杂项目中,多层嵌套条件编译常用于适配不同平台或构建变体。编译器按预处理指令自上而下解析,逐层判断条件是否成立。
嵌套结构的执行顺序
编译器首先评估外层条件,仅当外层为真时才进一步解析内层条件。若外层为假,则整个嵌套块被忽略。

#ifdef DEBUG
    #ifdef VERBOSE
        printf("Debug verbose mode\n");
    #else
        printf("Debug mode\n");
    #endif
#else
    printf("Release mode\n");
#endif
上述代码中,DEBUG 必须定义才能进入内层判断;否则直接执行 #else 分支。嵌套层级可扩展,但建议控制在三层以内以提升可读性。
条件优先级与逻辑组合
通过 #if defined(A) && defined(B) 可实现复合判断,比嵌套更清晰。合理使用括号明确优先级,避免逻辑歧义。

第三章:调试开关的设计与应用

3.1 使用 #ifdef 控制调试信息输出

在C/C++开发中,#ifdef 是条件编译的常用指令,可用于灵活控制调试信息的输出。
基本用法
通过定义宏来开启或关闭调试代码:

#ifdef DEBUG
    printf("调试信息: 当前值 = %d\n", value);
#endif
当编译时未定义 DEBUG 宏,上述打印语句将被预处理器忽略,从而避免发布版本中输出调试信息。
编译控制示例
使用编译器选项定义宏:
  • gcc -DDEBUG main.c:启用调试模式
  • gcc main.c:默认不输出调试信息
该机制有效分离调试与发布代码,提升程序安全性与性能。

3.2 调试宏的封装技巧与日志级别管理

在大型系统开发中,调试信息的有效管理至关重要。通过封装调试宏,可实现灵活的日志控制与编译期优化。
日志级别的定义与使用
常见的日志级别包括 DEBUG、INFO、WARN、ERROR,可通过枚举或宏定义实现:
#define LOG_DEBUG 0
#define LOG_INFO  1
#define LOG_WARN  2
#define LOG_ERROR 3
#define LOG_LEVEL LOG_DEBUG
该定义允许在编译时根据 LOG_LEVEL 过滤输出,减少运行时开销。
条件编译的宏封装
使用预处理器指令封装日志输出,实现按级别过滤:
#define DEBUG_PRINT(level, fmt, ...) \
    do { \
        if (level >= LOG_LEVEL) \
            fprintf(stderr, "[%s] " fmt "\n", #level, ##__VA_ARGS__); \
    } while(0)
宏中 ##__VA_ARGS__ 处理可变参数,do-while(0) 确保语法安全。结合编译选项(如 -DLOG_LEVEL=LOG_WARN),可在发布版本中关闭调试输出,提升性能。

3.3 发布版本中安全关闭调试代码的方法

在发布版本中,调试代码若未妥善处理,可能暴露敏感信息或引发安全漏洞。因此,必须通过规范化手段将其安全关闭。
使用编译标签控制调试模式
Go语言支持构建标签(build tags),可在编译时决定是否包含调试代码。例如:
//go:build debug
package main

import "log"

func init() {
    log.Println("调试模式已启用")
}
该代码仅在启用 `debug` 标签时编译生效:`go build -tags debug`。发布时省略该标签即可彻底移除调试逻辑,避免运行时开销。
环境变量与日志级别控制
通过配置日志等级,动态控制输出内容:
  • 开发环境设置为 DEBUG 级别
  • 生产环境强制使用 ERROR 或 WARN 级别
此方法结合条件编译,实现多层级安全防护,确保发布版本不泄露内部状态。

第四章:实战中的高级用法与陷阱规避

4.1 条件编译实现跨平台代码适配

在多平台开发中,条件编译是实现代码适配的核心技术之一。通过预处理器指令,可根据目标平台选择性地编译代码片段,从而屏蔽系统差异。
常用预定义宏
不同编译环境会自动定义特定宏,例如:
  • __linux__:Linux 平台
  • _WIN32:Windows 平台
  • __APPLE__:macOS/iOS 平台
代码示例与分析

#include <stdio.h>

int main() {
#if defined(_WIN32)
    printf("Running on Windows\n");
#elif defined(__linux__)
    printf("Running on Linux\n");
#elif defined(__APPLE__)
    printf("Running on Apple system\n");
#else
    printf("Unknown platform\n");
#endif
    return 0;
}
该代码通过 #if defined() 检查平台宏,输出对应信息。预处理器在编译前仅保留匹配平台的代码分支,其余被剔除,不参与编译,从而实现零运行时开销的平台适配。
优势与适用场景
条件编译适用于需静态分离逻辑的场景,如系统调用封装、头文件包含控制和API函数映射。

4.2 避免 #ifdef 滥用导致的代码可维护性下降

在跨平台或条件编译场景中,#ifdef 被广泛用于启用或禁用特定代码段。然而,过度使用会导致代码分支爆炸,降低可读性和测试覆盖率。
问题示例

#ifdef DEBUG
    printf("调试信息: %d\n", value);
#endif

#ifdef PLATFORM_LINUX
    do_linux_specific();
#elif defined(PLATFORM_WINDOWS)
    do_windows_specific();
#endif
上述代码嵌套条件编译,使逻辑分散,难以追踪执行路径。
优化策略
  • 使用抽象接口替代条件编译,如定义统一的日志函数
  • 通过构建系统控制模块引入,而非在源码中硬编码平台差异
  • 将平台相关实现隔离到独立文件,按目标平台编译链接
重构示例

// 统一日志接口
void log_info(const char* msg) {
#ifdef DEBUG
    printf("[INFO] %s\n", msg);
#endif
}
将条件逻辑封装在函数内部,调用方无需感知预处理分支,提升代码整洁度与可维护性。

4.3 编译时配置选项的集中化管理

在大型项目中,分散的编译配置易导致构建不一致。通过集中化管理,可统一控制编译行为。
配置文件结构设计
采用单一配置源(如 `build.config`)定义所有编译参数,提升可维护性:
# build.config
ENABLE_OPTIMIZATION=true
DEBUG_SYMBOLS=false
TARGET_ARCH=x86_64
上述变量可在 Makefile 或 CMake 中动态读取,实现条件编译。
集成构建系统
使用 CMake 时,通过 CMakeLists.txt 引入集中配置:
if(ENABLE_OPTIMIZATION)
  add_compile_options(-O2)
endif()
逻辑上根据配置项自动启用优化选项,避免手动干预。
配置优先级管理
  • 默认配置:提供基础编译参数
  • 环境覆盖:支持 CI/CD 覆盖关键选项
  • 本地调试:开发者可临时启用调试符号
该层级机制确保灵活性与一致性并存。

4.4 常见误用场景分析与修正方案

并发写入导致数据竞争
在高并发环境下,多个 goroutine 直接操作共享 map 而未加锁,将引发 panic。

var cache = make(map[string]string)
var mu sync.RWMutex

func Set(key, value string) {
    mu.Lock()
    defer mu.Unlock()
    cache[key] = value
}
使用 sync.RWMutex 可安全保护读写操作,避免竞态条件。读多写少场景下推荐使用读写锁提升性能。
资源泄漏与超时缺失
HTTP 客户端未设置超时,导致连接堆积:
配置项错误示例修正方案
Timeoutnil30秒全局超时
MaxIdleConns默认限制为100

第五章:从底层机制到工程最佳实践

理解内存对齐对性能的影响
在高性能 Go 服务中,结构体字段的排列顺序直接影响内存占用与访问速度。例如,以下结构体未优化:

type BadStruct struct {
    a byte     // 1 字节
    b int64    // 8 字节(需 8 字节对齐)
    c int16    // 2 字节
}
// 总大小:24 字节(含填充)
通过重排字段可减少内存浪费:

type GoodStruct struct {
    b int64    // 8 字节
    c int16    // 2 字节
    a byte     // 1 字节
    // 填充 5 字节
}
// 总大小:16 字节
连接池配置的最佳实践
数据库连接池若配置不当,易引发资源耗尽或连接争用。以下是 PostgreSQL 连接池的合理设置建议:
参数推荐值说明
MaxOpenConns核心数 × 2 ~ 4避免过多并发连接压垮数据库
MaxIdleConnsMaxOpenConns × 0.5保持适量空闲连接以降低建立开销
ConnMaxLifetime30 分钟防止 NAT 中间件超时断连
优雅关闭服务的实现策略
为确保正在处理的请求不被中断,应监听系统信号并逐步关闭服务:
  • 注册 SIGTERM 和 SIGINT 信号处理器
  • 停止接收新请求(关闭监听端口)
  • 启动超时计时器(如 30 秒)
  • 等待活跃连接完成处理
  • 释放数据库连接、关闭日志写入器等资源

优雅关闭流程: 接收信号 → 停止监听 → 通知负载均衡下线 → 等待请求结束 → 释放资源

C语言条件编译#if_#elif_#ifdef_#ifndef 假如要开发一款产品,开始的程序一般会利用前面已开发完毕的程序,但是程序的时钟可能不是我们需要的,时钟的变化会导致串口波特率的产生偏差,这时候我们可以利用宏来选择 /************系统时钟频率定义,主要用于配置UART波特率**********/ #if (SYSCLK_SRC == IRCH) #define FOSC (3686400) #elif (SYSCLK_SRC == PLL) #define PLL_Multiple 6 //PLL倍频倍数 #de... 阅读详情

相关推荐

C语言条件编译(#if,#ifdef,#ifndef,#endif,#else,#elif)

C语言条件编译(#if,#ifdef,#ifndef,#endif,#else,#elif)

qq_33300585的博客 2865

ifndef详解

ifndef详解 #ifndef 是"if not defined"的简写,是预处理功能(宏定义、文件包含、条件编译)当中的条件编译,可以根据是否已经定义了一个变量来进行分支选择,其作用是: 防止头文件的重复包含和编译; 便于程序的调试和移植; 下面分别举例描述。 一、防止头文件的重复包含和编译 下面是错误示范: headfile_1.h 1 #include <iostream> 2 class CTest_1 { 3 CTest_1() { 4 //do

weixin_42692164的博客 5万+

C++ 预处理编译指令#ifndef | 九七的C++教程

C++ 预处理编译指令#ifndef 一、介绍 定义介绍: #ifndef条件指示符是c++中的预处理编译指令,是一种宏定义,它是以根据是否已经定义了一个变量来进行分支选择。通常与#endif搭配使用。 实现功能: 判断名称是否被#define定义过,防止头文件多重包含,避免重复出错。如果使用#ifndef加名称,发现名称已经被定义,返回false,直接跳出#endif,执行#endif后面的内容;如果未定义,则执行#ifndef到#endif之间的语句。 作用范围: #ifndef后面跟的是一个名称,可以

九七的博客 3643

条件编译#ifdef的妙用详解_透彻

本文主要介绍c语言中条件编译相关的预编译指令,包括#define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined。 #define 定义一个预处理宏 #undef 取消宏的定义 #if 编译预处理中的条件命令,相当于C语法中的if语句 #ifdef ...

look_distance的博客 9377

记录 | C++ #ifdef #endif 条件编译指令

记录 | C++ #ifdef #endif 条件编译指令

极智视界 1497

C/C++ 条件编译指令详解:#if、#ifdef、#ifndef 的区别与最佳实践

C/C++预处理指令对比与应用 #if、#ifdef和#ifndef是C/C++中常用的条件编译指令,主要区别在于判断条件不同:#if基于表达式值,#ifdef检查宏是否定义,#ifndef检查宏是否未定义。#ifdef常用于调试控制和平台适配,#ifndef主要用于防止头文件重复包含,而#if支持更复杂的条件判断和版本控制。三者可组合使用,结合defined()运算符实现灵活的条件编译。最佳实践包括使用标准头文件保护、合理的命名规范以及平台检测宏。这些指令在跨平台开发、功能定制和代码优化中发挥重要作用。

学无止境 4175

#if、#else、#endif、#elif、#ifdef、#ifndef的区别和使用

常用的条件编译 #if, #elif,#else,#endif,#ifdef、#ifndef 看名字就知道,跟我们平时用的if、elseif、else是 一样的,不同的是这里一定要记得 #endif。 #if 条件 1  代码 1 #elif 条件 2  代码 2 #else  代码段 n+1 #endif 意思跟我们平常写的代码一样,如果条件1成立,则编译代码1,如果条件二成立,则编...

qingfeng_博客 3万+

ATAC-seq数据分析流程

Outline0. ATAC-seq原理0.1 染色体结构0.2 原理0.3 结果0.4 意义1. ATAC-seq数据分析流程1.1 上游分析(1)序列质控和比对(2)序列筛选1.2 下游分析1.3 进阶分析 0. ATAC-seq原理 0.1 染色体结构 0.2 原理 0.3 结果 0.4 意义 1. ATAC-seq数据分析流程 1.1 上游分析 (1)序列质控和比对 fastqc trim_golare bowtie2 mapping时要加上参数 --very-sensitive -X 2000

weixin_57830892的博客 1万+

深度解析条件编译:#ifdef与#ifndef的本质区别与应用实践

/ 根据条件定义不同的宏#else#endif// 使用条件定义函数宏(a) : (b))#endif(a) : (b))#endif#endifreturn 0;// 错误示例:直接使用可能未定义的标识符// 如果DEBUG_LEVEL未定义会出错#endif// 正确做法:提供默认值或额外检查#endif#endif通过本文的深入探讨,我们已经全面了解了#ifdef和#ifndef这两个关键预处理指令的区别、用法和最佳实践。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 2000

国产FPGA逆袭!深度评测复旦微RFVU3P5G核心板在相控阵雷达中的表现

本文深度评测了复旦微RFVU3P5G核心板在相控阵雷达中的实战表现。该核心板凭借射频直采架构、高采样率ADC/DAC及丰富的DSP资源,在多通道同步精度、动态范围及系统稳定性等关键指标上表现出色,展现了国产FPGA在高端雷达应用中的硬核实力与供应链自主价值。

b0c1d2的博客 724

CSR-DCF视频目标跟踪源码运行笔记

论文基本信息 论文标题:Discriminative Correlation Filter with Channel and Spatial Reliability 论文作者:Alan Lukezic等 论文出处:CVPR 2017 文章链接:https://arxiv.org/abs/1611.08461 补充材料:https://www.semanticscholar.org/paper/D...

越野者的博客 3400

【C语言】#ifdef和#endif条件编译

条件编译

zhang2929259676的博客 1万+

微信公众号数据采集实战:历史文章、互动数据与评论详情全解析

本文提供了一套完整的微信公众号数据采集实战方案,详细解析了如何通过接口调用获取公众号的历史文章列表、单篇文章的互动数据以及详细的用户评论。文章从环境准备、核心参数解析到分页逻辑、批量处理和异常处理,提供了可运行的Python代码示例,旨在帮助开发者高效、稳定地构建自动化采集工具,用于竞品分析、内容研究和舆情监控。

u5v6w7的博客 1596

条件编译#if,#ifdef,#ifndef区别

原文章:https://www.cnblogs.com/yanwei-wang/p/8073114.html #if,#ifdef,#ifndef的区别 #if,#ifdef,#ifndef的区别一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,也就是条件编译。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。 ifdef 如: #ifdef标识符 程序段1 #else 程序段2 #endif 它的作

nb_zsy的博客 1653

什么是 SAPGUI 里的 Logon Group/Server

这意味着,不同的用户连接可以被分配到不同的应用服务器,以实现均衡的资源利用和降低某一服务器的负载压力。在这种配置下,欧洲的用户登录时选择“EUROPE_GROUP”,系统将自动选择一个位于欧洲的数据中心的服务器进行连接,这样不仅减少了网络延迟,还实现了服务器间的负载均衡。用户在 SAPGUI 中登录时,只需选择相应的 Logon Group(例如“FIN_GROUP”),系统就会自动将他们的连接请求分配到当前负载最小的应用服务器上,这种动态分配大大提升了系统的响应速度和稳定性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1069

反激电源及其变压器计算与绕制

本内容以一个宽电压输入 24V3A 输出的 72W 反激电源为例来计算电路的各个参数和器件选型,包含反激变压器的计算与绕制方法。

让你爱上电路设计 1935

讲通C/C++预编译/条件编译指令 #ifdef,#ifndef,#endif,#define,…

讲清楚C/C++预处理指令#define,#ifdef,#ifndef,#endif…等的妙用,作为阅读redis源码的首战!

看,未来的博客 5352

Python爬虫实战:携程旅游攻略爬取全流程解析(动态接口+反爬破解+异步爬取)

本文介绍了携程旅游攻略的爬取全流程,涵盖静态和动态页面抓取、异步请求、高级反爬策略以及数据存储和简单分析。增加用户评论和评分抓取结合NLP分析攻略文本情感与关键词建立旅游推荐系统自动化代理IP池和验证码识别模块。

2201_76125261的博客 2039

C/C++#if #ifdef #ifndef的区别

用条件编译,则不必一一删改printf语句,只需删除前面的一条“#define DEBUG”命令即可,这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用,即起统一控制的作用,如同一个“开关”一样。的确,此问题完全可以不用条件编译处理,但那样做目标程序长(因为所有语句都编译),而采用条件编译,可以减少被编译的语句,从而减少目标的长度。现在先定义LETTER为1,这样在预处理条件编译命令时,由于LETTER为真(非零),则对第一个if语句进行编译,运行时使小写字母变大写。

墨痕诉清风的博客 1165

【Claude】组织级认证限制报错已解决(4 种)

报错被禁用的是什么谁能解除应急方案整个 Console 组织Anthropic 支持换账户 / 订阅凭证API key 认证方式你的组织管理员用订阅/login订阅 OAuth 登录你的组织管理员用 API keyRoutines 功能你的组织所有者手动计划任务替代共同排查模式/status确认当前凭证;检查环境变量;看清报错消息里命名的是什么(key?组织访问?),对症清除;管理员层面的限制,找管理员解锁。

博客 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

uni-app #ifdef #ifndef #endif的使用和区别

条件编译是一种在编程中根据特定平台选择性编译代码的技术。如#ifdef和#endif根据APP-PLUS平台标识在微信小程序、支付宝小程序、百度小程序、头条小程序、QQ小程序以及H5应用中实现代码的平台特定执行。下面介绍了如何使用#ifdef和#ifndef等注释来标记代码块,确保它们在H5、5+App、微信小程序等不同平台上正确执行编译。通过这种方式,开发者可以实现代码的平台定制,提高代码的可移植性和效率。

qq_36158551的博客 3024

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

#if,#ifdef,#ifndef的区别

#if,#ifdef,#ifndef的区别一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件 编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。 条件编译命令最常见的形式为: ********************************************­ #i...

m0_37931718的博客 669

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C语言条件编译(#if,#ifdef,#ifndef,#endif,#else,#elif)!

条件编译(conditional compiling)命令指定预处理器依据特定的条件来判断保留或删除某段源代码。 例如,可以使用条件编译让源代码适用于不同的目标系统,而不需要管理该源代码的各种不同版本。 条件编译区域以 #if、#ifdef 或 #ifndef 等命令作为开头,以 #endif 命令结尾。条件编译区域可以有任意数量的 #elif 命令,但最多一个 #else 命令。以 #if 开头的条件编译区域具有下面的格式: #if 表达式1 [ 组1] [#elif 表达式2 ..

HUYA69的博客 1534

条件编译#if、#ifdef、#ifndef 及#define和const区别

文章目录1、#ifndef的作用2、头文件被重复引用会怎么样?3、头文件中都要加入#ifndef/#define/#endif ?4、#ifndef/#define/#endif 具体含义5、#ifndef/#define/#endif 示例6、 #if,#ifdef, #ifndef 的比较7、const 与 #define的比较 1、#ifndef的作用 1、头文件中使用,防止头文件被多重调用。 被重复引用是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于includ

lucky_zbaby的博客 957

预处理命令#if #define #ifdef #ifndef等

由于 在coding中,会有重复的代码段或者有一些逻辑代码处理,需要对比或者分情况实现运行,这个时候,相应的预处理命令便开始起到不可或缺的重要!!这里对预处理命令做一个详细的总结。格式:#define 标识符 字符串10int main()需要注意的一点是,不管是在某个函数内,还是在所有函数之外(不太建议把#define写在函数内),#define作用域都是从定义开始直到整个文件结尾(这一点和typedef就区别很大)#define(宏定义)----由预处理器来处理。

weixin_45671864的博客 2554

条件编译#if、#elif、#ifdef的妙用

般情况下,C语言源程序中的每一行代码.都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。相关的预编译指令如下:

weixin_39266374的博客 2713
上一篇: 【C语言预处理黑科技】:带你玩转带参数宏的8种实战场景
下一篇: register优化失效?深入汇编层面解析编译器真实处理机制
VarLens
博客等级 码龄1年 168粉丝 2188原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值