当前位置: 首页 > 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 的缩写。

http://www.lryc.cn/news/26201.html

相关文章:

  • Linux: ARM GIC只中断CPU 0问题分析
  • 测试软件5
  • 前端JS内存管理
  • 第七章.集成学习(Ensemble Learning)—袋装(bagging),随机森林(Random Forest)
  • Java_面向对象
  • 【IoT】智能烟雾报警器
  • Python实现定时执行脚本(5)
  • JavaSe第4次笔记
  • epoll机制
  • Java使用不同方式获取两个集合List的交集、补集、并集(相加)、差集(相减)
  • 【Android笔记80】Android之Retrofit适配器和文件上传下载
  • Nodejs模块化
  • C++STL基础
  • 数学建模经验【更新中】
  • 【python学习笔记】:Excel 数据的封装函数
  • 如何获取或设置CANoe以太网网卡信息(GET篇)
  • “终于我从字节离职了...“一个年薪50W的测试工程师的自白...
  • 【Spring】八种常见Bean加载方式
  • 第五回:样式色彩秀芳华
  • 关于@Test单元测试
  • 【项目实战】WebFlux整合r2dbc-mysql实战
  • go版本分布式锁redsync使用教程
  • 大数据之Hudi数据湖_大数据治理_简介_发展历史_特性_应用场景---大数据之Hudi数据湖工作笔记0001
  • 射频功率放大器基于纵向导波的杆状构件腐蚀诊断方法的研究
  • Leedcode 二分查找 理解1
  • 【告别篇】大家好,再见了,我转行了,在筹备创业
  • Java——岛屿数量
  • 《代码整洁之道》笔记
  • 个人网站如何集成QQ快捷登录功能?
  • 从工厂打螺丝到月薪18k测试工程师,我该满足吗?