当前位置: 首页 > news >正文

C语言 条件编译

目录

1. #if  #elif #else #endif

2. #ifdef #else #endif

3. #ifndef #else #endif

4. 三者区别


根据不同情况编译不同代码、产生不同目标文件的机制,称为条件编译

条件编译是预处理程序的功能,不是编译器的功能。

1. #if  #elif #else #endif

#if 的一般格式为:

#if 整型常量表达式1程序段1
#elif 整型常量表达式2程序段2
#elif 整型常量表达式3程序段3
#else程序段4
#endi

它的意思是:如常“表达式1”的值为真(非0),就对“程序段1”进行编译,否则就计算“表达式2”,结果为真的话就对“程序段2”进行编译,为假的话就继续往下匹配,直到遇到值为真的表达式,或者遇到 #else。这一点和 if else 非常类似。

需要注意的是,#if 命令要求判断条件为“整型常量表达式”,也就是说,表达式中不能包含变量,而且结果必须是整数;而 if 后面的表达式没有限制,只要符合语法就行。这是 #if 和 if 的一个重要区别。

#elif 和 #else 也可以省略,如下所示:

#include <stdio.h>
int main(){#if _WIN32printf("This is Windows!\n");#elseprintf("Unknown platform!\n");#endif#if __linux__printf("This is Linux!\n");#endifreturn 0;
}

2. #ifdef #else #endif

#ifdef 用法的一般格式为:

#ifdef  宏名程序段1
#else程序段2
#endif

它的意思是,如果当前的宏已被定义过,则对“程序段1”进行编译,否则对“程序段2”进行编译。

也可以省略 #else:

#ifdef  宏名程序段
#endif

示例:

#include <stdio.h>
#include <stdlib.h>
int main(){#ifdef _DEBUGprintf("正在使用 Debug 模式编译程序...\n");#elseprintf("正在使用 Release 模式编译程序...\n");#endifsystem("pause");return 0;
}

3. #ifndef #else #endif

#ifndef 用法的一般格式为:

#ifndef 宏名程序段1 
#else 程序段2 
#endif

与 #ifdef 相比,仅仅是将 #ifdef 改为了 #ifndef。它的意思是,如果当前的宏未被定义,则对“程序段1”进行编译,否则对“程序段2”进行编译,这与 #ifdef 的功能正好相反。

#ifndef 在头文件可用于避免文件被重复包含。

#ifndef  _PRJ_DIR_FILE_H  //必须确保header guard宏名永不重名
#define  _PRJ_DIR_FILE_H//<头文件内容>#endif

4. 三者区别

#if 后面跟的是“整型常量表达式”,而 #ifdef 和 #ifndef 后面跟的只能是一个宏名,不能是其他的。

例如,下面的形式只能用于 #if:

#include <stdio.h>
#define NUM 10
int main(){#if NUM == 10 || NUM == 20printf("NUM: %d\n", NUM);#elseprintf("NUM Error\n");#endifreturn 0;
}

再如,两个宏都存在时编译代码A,否则编译代码B:

#include <stdio.h>
#define NUM1 10
#define NUM2 20
int main(){#if (defined NUM1 && defined NUM2)//代码Aprintf("NUM1: %d, NUM2: %d\n", NUM1, NUM2);#else//代码Bprintf("Error\n");#endifreturn 0;
}

#ifdef 可以认为是 #if defined 的缩写。

相关文章:

C语言 条件编译

目录 1. #if #elif #else #endif 2. #ifdef #else #endif 3. #ifndef #else #endif 4. 三者区别 根据不同情况编译不同代码、产生不同目标文件的机制&#xff0c;称为条件编译。 条件编译是预处理程序的功能&#xff0c;不是编译器的功能。 1. #if #elif #else #endif …...

Linux: ARM GIC只中断CPU 0问题分析

文章目录1. 前言2. 分析背景3. 问题4. 分析4.1 ARM GIC 中断芯片简介4.1.1 中断类型和分布4.1.2 拓扑结构4.2 问题根因4.2.1 设置GIC SPI 中断CPU亲和性4.2.2 GIC初始化&#xff1a;缺省的CPU亲和性4.2.2.1 boot CPU亲和性初始化流程4.2.2.1 其它非 boot CPU亲和性初始化流程5.…...

测试软件5

一 css基础 css定义&#xff1a;可以设置网页中的样式&#xff0c;外观&#xff0c;美化 css中文名字&#xff1a;级联样式表&#xff0c;层叠样式表&#xff0c;样式表 二 css基础语法 1.style标签写在title标签后面 2.选择器{属性名1&#xff1a;属性值1&#xff1b;属性名…...

前端JS内存管理

JS内存管理 内存原理&#xff1a; 任何变成语言在执行的时候都需要操作系统来分配内存&#xff0c;只是有些语言需要手动管理分配的内存有些语言有专门来管理内存的方式 如 JVM 了解以上的概念之后&#xff0c;我们再来了解一下大致的内存周期 分配需要的内存使用内存在不使用…...

第七章.集成学习(Ensemble Learning)—袋装(bagging),随机森林(Random Forest)

第七章.集成学习 (Ensemble Learning) 7.1 集成学习—袋装(bagging),随机森林(Random Forest) 集成学习就是组合多个学习器&#xff0c;最后得到一个更好的学习器。 1.常见的4种集成学习算法 个体学习器之间不存在强依赖关系&#xff0c;袋装&#xff08;bagging&#xff09;…...

Java_面向对象

Java_面向对象 1.面向对象概述 ​ 面向对象是一种符合人类思想习惯的编程思想。显示生活中存在各种形态的不同事物&#xff0c;这些食物存在着各种各样的联系。在程序中使用对象来映射现实中的事物&#xff0c;使用对象的关系来描述事物之间的关系&#xff0c;这种思想就是面…...

【IoT】智能烟雾报警器

设计简介 硬件设计由AT89C51单片机、DS18B20温度传感器、4位共阳数码管、电源模块、报警模块、按键模块、MQ-2烟雾检测模块和ADC0832模数转换模块组成。 烟雾传感器MQ-2检测空气中的烟雾气体&#xff0c;通过ADC0832进行数据转换&#xff0c;经过单片机的运算处理后在数码管上…...

Python实现定时执行脚本(5)

前言 本文是该专栏的第17篇,后面会持续分享python的各种干货知识,值得关注。 笔者在前面有详细介绍过几种使用python实现定时执行任务的方法,可以说都是简单易上手的那种。而本文,再来详细介绍另外一种定时方法,那就是利用任务框架APScheduler(advanceded python schedu…...

JavaSe第4次笔记

1.转义字符和编程语言无关。 2.斜杠(\)需要转义&#xff0c;反斜杠(/)不需要转义。 3.不能做switch的参数的数据类型&#xff1a;long float double boolean( String可以)。 4.输入的写法&#xff1a;Scanner(回车自动带头文件(import java.util.Scanner;)) Scanner scan …...

epoll机制

预备知识 文件描述符file descriptor 文件描述符是Linux系统中对文件、套接字等I/O资源的抽象&#xff0c;每个打开的文件或套接字都有一个唯一的文件描述符。应用程序可以使用文件描述符来读写文件或进行网络通信。 epoll允许程序监控多个文件描述符&#xff0c;以便在这些…...

Java使用不同方式获取两个集合List的交集、补集、并集(相加)、差集(相减)

1 明确概念首先知道几个单词的意思&#xff1a;并集 union交集 intersection补集 complement析取 disjunction减去 subtract1.1 并集对于两个给定集合A、B&#xff0c;由两个集合所有元素构成的集合&#xff0c;叫做A和B的并集。记作&#xff1a;AUB 读作“A并B”例&#…...

【Android笔记80】Android之Retrofit适配器和文件上传下载

这篇文章,主要介绍Android之Retrofit适配器和文件上传下载。 目录 一、Retrofit适配器 1.1、Retrofit适配器 (1)引入RxJava依赖 (2)定义接口...

Nodejs模块化

1.模块化 1.1.模块化的基本概念 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分为若干模块的过程。对于整个系统而言&#xff0c;模块是可组合、分解和更换的单元。 1.2 编程中的模块化 编程领域的模块化就是把一个大文件拆成独立并相互依赖的多个小模块…...

C++STL基础

STL基础 诞生 cpp的面向对象和泛型编程的思想本质就是提高复用性诞生了STL库 基本概念 STL标准模板库STL从广义上分为容器、算法及迭代器容器和算法之间通过迭代器进行连接STL几乎所有的代码都采用了模板类或者模板函数 基本组件 容器、算法、迭代器、仿函数、适配器、空间配置…...

数学建模经验【更新中】

数学建模简单入门 一、 分工 3人&#xff0c;1人论文&#xff0c;1人代码主力&#xff0c;1人论文代码&#xff08;前一半时间主代码&#xff0c;后一半时间主论文&#xff09; Tips: 不养闲人&#xff0c;论文必须要在对代码和题目极其了解并且能跟上队友思路的情况下才能写…...

【python学习笔记】:Excel 数据的封装函数

对比其它编程语言&#xff0c;我们都知道Python最大的优势是代码简单&#xff0c;有丰富的第三方开源库供开发者使用。伴随着近几年数据分析的热度&#xff0c;Python也成为最受欢迎的编程语言之一。而对于数据的读取和存储&#xff0c;对于普通人来讲&#xff0c;除了数据库之…...

如何获取或设置CANoe以太网网卡信息(GET篇)

CAPL提供了一系列函数用来操作CANoe网卡。但是,但是,首先需要明确一点,不管是获取网卡信息,还是设置网卡信息,只能访问CAPL程序所在的节点下的网卡,而不是节点所在的以太网通道下的所有网卡 关于第一张图中,Class节点下,有三个网卡:Ethernet1、VLAN 1.100、VLAN 1.200…...

“终于我从字节离职了...“一个年薪50W的测试工程师的自白...

我递上了我的辞职信&#xff0c;不是因为公司给的不多&#xff0c;也不是因为公司待我不好&#xff0c;但是我觉得&#xff0c;我每天看中我憔悴的面容&#xff0c;每天晚上拖着疲惫的身体躺在床上&#xff0c;我都不知道人生的意义&#xff0c;是赚钱吗&#xff1f;是为了更好…...

【Spring】八种常见Bean加载方式

&#x1f6a9;本文已收录至专栏&#xff1a;Spring家族学习 一.引入 (1) 概述 ​ 关于bean的加载方式&#xff0c;spring提供了各种各样的形式。因为spring管理bean整体上来说就是由spring维护对象的生命周期&#xff0c;所以bean的加载可以从大的方面划分成2种形式&#xff…...

第五回:样式色彩秀芳华

import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np第五回详细介绍matplotlib中样式和颜色的使用&#xff0c;绘图样式和颜色是丰富可视化图表的重要手段&#xff0c;因此熟练掌握本章可以让可视化图表变得更美观&#xff0c;突出重点和凸显艺术性。…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...