返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >深入浅析C/C++ 的条件编译
  • 928
分享到

深入浅析C/C++ 的条件编译

2024-04-02 19:04:59 928人浏览 薄情痞子
摘要

目录1.条件编译的时机2.条件编译的作用3.#if #else #endif4.#ifndef #define #endif5.#if #elif #else #endif6.#if

1.条件编译的时机

我们都知道vscode其实是一个编辑器,你要在上面跑C或者c++你需要配置编译器,拿编译器是怎样吧一个文本文件变成一个可执行文件的呢?

那必然是经历以下这四步

  • 处理:宏替换,头文件的展开,去注释,条件编译
  • 编译:将预处理后的源文件转换为汇编语言文件,只编译源文件,不编译头文件,头文件在刚刚预处理阶段已经展开。
  • 汇编:虽然叫做汇编,但是不是转变为汇编代码,而是将刚刚的汇编语言文件转换为机器码,也就是二进制文件。
  • 链接:将生成的二进制代码与库函数以及其他目标文件,通过链接器链接起来形成可执行文件的过程。

分析了以上过程由此可以很清晰的得出这个结论,条件编译是在预处理的时候发生的。

2.条件编译的作用

条件编译是指预处理的时候根据条件编译的指令有条件的选择源程序中的一部分代码送给编译器进行编译,进行有选择性的操作,防止宏替换的内容重复包含。

常见的条件编译指令如下:

常见条件编译指令

3.#if #else #endif

#if 表达式
 
// code
#else
#endif

如果表达式为真则#if后程序段被调用

明显发现第一段的色段跟第二段的色段都不一样!肯定是第一句输出了!

可以看到他直接call调用的就是标准命名空间下的operator类里面的函数,其实也就是 << 输出

4.#ifndef #define #endif

#ifdef 标识符
#define 标识符 替换列表
 
// code
#endef
  • 一般用于检测程序中是否已经定义了名字为某标识符的宏,如果没有定义该宏,则定义该宏,并选中从 #define 开始到 #endif 之间的程序段;
  • 如果已定义,则不再重复定义该符号,且相应程序段不被选中。

我们都知道NULL在C中是一个宏,宏有时也会引起不必要的问题在C++11中则有了nullptr,所以这块显示是已经被宏过了,所有不执行#define 到#endef的程序段所以看起来是灰色的。

红色框框是每个函数都有的,就是主函数栈帧开辟和销毁的过程,再看中间好家伙啥都没有,再次印证了,我们说的如果没有定义该宏,则定义该宏,并选中从 #define 开始到 #endif 之间的程序段;如果已定义,则不再重复定义该符号,且相应程序段不被选中。

该条件编译指令更重要的一个应用是防止头文件重复包含。

如果 f.c 源文件中包含 f1.h 和 f2.h 两个头文件,而 f1.h 头文件及 f2.h 头文件中均包含 f3.h 头文件,则 f.c 源文件因为包含了 f1.h 和 f2.h 两个头文件,所以中重复包含 f3.h 头文件。可采用条件编译指令,来避免头文件的重复包含问题。

#ifndef _HEADNAME_H_
#define _HEADNAME_H_
    //头文件内容
#endif
  • 当该头文件第一次被包含时,由于没检测到该头文件名对应的宏名,则定义该头文件名对应的宏,其值为该系统默认。并且,该条件编译指令选中 #endif 之前的头文件内容;
  • 如果该头文件再次被包含时,由于检测到已存在以该头文件名对应的宏名,则忽略该条件编译指令之间的所有代码,从而避免了重复包含。

5.#if #elif #else #endif

#if 条件表达式1
 
    // code1
#elif 条件表达式2
    //code 2
#else
        
    //code 3
#endif
  • 功能为:先判断条件1的值,如果为真,则程序段 1 被选中编译;
  • 如果为假,而条件表达式 2 的值为真,则程序段 2 被选中编译;
  • 其他情况,程序段 3 被选中编译。

6.#ifdef #endif

#ifdef 标识符
    //code
#endif
  • 如果检测到已定义该标识符,则选择执行相应程序段被选中编译;
  • 否则,该程序段会被忽略。
#include <iOStream>
using namespace std;
#define PI 3.14
int main() {
#ifdef PI 
#undef PI
	cout << "PI 已经被取消宏" << endl;
#endif 
}

如果检测到符号 PI已定义,则删除其定义,并选中相应的程序段。

到此这篇关于深入浅析C/C++ 的条件编译的文章就介绍到这了,更多相关c++条件编译内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 深入浅析C/C++ 的条件编译

本文链接: https://lsjlt.com/news/147097.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 深入浅析C/C++ 的条件编译
    目录1.条件编译的时机2.条件编译的作用3.#if #else #endif4.#ifndef #define #endif5.#if #elif #else #endif6.#if...
    99+
    2024-04-02
  • C语言深入讲解条件编译的用处
    目录一、基本概念二、条件编译的本质三、#include 的本质四、条件编译的意义五、小结一、基本概念 条件编译的行为类似于 C 语言中的 if...else...编译是预编译指示命令...
    99+
    2024-04-02
  • 深入浅析Java中的Condition条件
    深入浅析Java中的Condition条件?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Condition介绍Condition的作用是对锁进行更精确的控制。Conditi...
    99+
    2023-05-31
    java condition ava
  • 深入浅析C++ traits技术
    前言   traits,又被叫做特性萃取技术,说得简单点就是提取“被传进的对象”对应的返回类型,让同一个接口实现对应的功能。因为STL的算法和容器是分离的,两者通过迭代器链接。算法的...
    99+
    2024-04-02
  • Vue3渲染器与编译器深入浅析
    目录渲染器相关概念渲染器阶段分析mount挂载阶段patch阶段简单实现编译器相关概念总结渲染器 相关概念 渲染器是Vue框架性能的核心,Vue3的渲染器不仅包含传统的Diff算法...
    99+
    2023-02-01
    Vue3渲染器编译器 Vue渲染编译
  • C#异步编程由浅入深(一)
    目录一、什么算异步?二、在编程中的异步三、原始的异步编程模式之回调函数1、回调函数一、什么算异步? 广义来讲,两个工作流能同时进行就算异步,例如,CPU与外设之间的工作流就是异步的。...
    99+
    2024-04-02
  • C语言条件编译怎么用
    本文小编为大家详细介绍“C语言条件编译怎么用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言条件编译怎么用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、基本概念条件编译的行为类似于 C 语言中的 if....
    99+
    2023-06-30
  • 深入浅析C语言与C++的区别与联系
    目录一、C语言是面向过程语言,而C++是面向对象语言1、面向过程和面向对象的区别2、面向过程和面向对象的优缺点面向过程语言面向对象语言二、具体语言上的区别1、关键字的不同2、后缀名不...
    99+
    2024-04-02
  • C#中条件编译、内联函数、CLS的示例分析
    这篇文章主要为大家展示了“C#中条件编译、内联函数、CLS的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#中条件编译、内联函数、CLS的示例分析”这篇文章吧。1、条件编译#if&nb...
    99+
    2023-06-29
  • C语言如何实现条件编译
    今天小编给大家分享一下C语言如何实现条件编译的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。通常情况,我们想让程序选择性地执行...
    99+
    2023-06-16
  • C#中有哪些条件编译指令
    这篇文章将为大家详细讲解有关C#中有哪些条件编译指令,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。C#条件编译指令用于按条件包含或排除源文件中的某些部分。按照语法的规定,C#条件编译指令必须...
    99+
    2023-06-18
  • 深入浅析C# 11 对 ref 和 struct 的改进
    目录前言背景ref 字段生命周期scopedunscopedref struct 约束反射实际用例栈上定长列表栈上链表未来计划高级生命周期总结前言 C# 11 中即将到来一个可以让重...
    99+
    2024-04-02
  • C#条件编译、内联函数、CLS介绍
    1、条件编译 #if 条件编译会隐藏非条件(#else if)代码,我们开发中很可能会忽略掉这部分代码,当我们切换条件常量到这部分代码时,很可能因为各种原因导致报错。 如果...
    99+
    2024-04-02
  • C语言深入浅出解析二叉树
    目录树概念及结构相关概念树的表示树在实际中的运用(表示文件系统的目录树结构)二叉树概念及结构概念需要注意的特殊二叉树二叉树的性质二叉树的存储结构顺序存储链式存储总结树概念及结构 树是...
    99+
    2024-04-02
  • 深入浅出分析C++ string底层原理
    目录一、深浅拷贝 浅拷贝:深拷贝二、string迭代器原理 三、string的传统写法 1.构造实现 2.其他接口 一、深浅拷贝 浅拷贝: 在实现string时要是不实先strin...
    99+
    2024-04-02
  • C++编译环境分析
    本篇内容介绍了“C++编译环境分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!源程序作为解释器输入,解释器可能会把程序转换为内部的合适的形...
    99+
    2023-06-17
  • C语言深入浅出分析函数指针
    我们先看一个代码: #include<stdio.h> void test() { printf("haha\n"); } int main() { printf("...
    99+
    2024-04-02
  • 深入浅析Java中的条件控制与循环控制
    今天就跟大家聊聊有关深入浅析Java中的条件控制与循环控制,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。条件控制语句:1. if-else语句if(条件1){代码块1;}else i...
    99+
    2023-05-31
    java 循环控制 条件控制
  • 深入浅析Python字符编码
    Python的字符串编码规则一直让我很头疼,花了点时间研究了下,并不复杂。主要涉及的内容有常用的字符编码的特点,并介绍了在python2.x中如何与编码问题作战,本文关于Python的内容仅适用于2.x,3...
    99+
    2022-06-04
    字符 Python
  • C#异步编程由浅入深(三)之详解Awaiter
      上一篇末尾提到了Awaiter这个类型,上一篇说了,能await的对象,必须包含GetAwaiter()方法,不清楚的朋友可以看上篇文章。那么,Awaiter...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作