Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >宏替换、条件编译、头文件展开

宏替换、条件编译、头文件展开

作者头像
海盗船长
发布于 2020-08-27 09:21:48
发布于 2020-08-27 09:21:48
2.3K00
代码可运行
举报
文章被收录于专栏:基础知识文章基础知识文章
运行总次数:0
代码可运行

宏替换、文件编译和头文件的展开

程序执行的几个步骤:

1.预处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
①将头文件展开

②宏替换

③条件编译

④去掉注释

2.编译:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
①语义语法纠错

②将.c文件编译成汇编语言

3.汇编:将汇编语言变成二进制机器语言

4.链接:将所有的目标文件和依赖的库文件进行汇总,得到最终的可执行程序 以下开发工程中经常用到的部分预处理指令:

#define <#macro#> // 定义宏

#undef <#macro#> // 取消宏

#if <#condition#> // 如果给定的condition为真,则编译下面的代码

#ifdef <#macro#> // 如果宏已定义,则编译下面的代码

#ifndef <#macro#> // 如果宏没有被定义,则编译下面的代码

#elif <#condition#> 如果前面的#if给定条件为假,当前的条件为真,则编译下面的代码

#endif // 结束一个#if…#else条件编译块

#error <#message#> // 停止编译并显示错误信息

宏的定义

#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏或定义宏。

宏替换

步骤: ①在调用宏时,首先对参数进行检查,看看是否包含了任何由#define定义的符号。如果是它们首先被替换。 ②替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替代。 ③最后,再次对文本结果进行扫描,看看是否包含了任何由#define定义的符号。如果是就重复上述处理过程。 这样,宏定义参数和#define定义可以包含其他#define定义的符号。但是,宏不可以出现递归。 例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define PRINT(Val) printf(#Val " = %d\n", Val)	
//期望打印的值是:
	//10+20 = 30
	PRINT(10+20);
	//相当于
	printf("10+20" " = %d\n", 10 + 20);

宏中的运算符

在定义宏时,经常会出现的两个运算符 # 和 ##

#:出现在宏定义中的#运算符,会将其后面参数转化为一个字符串。我们把这种用法的成为字符串化运算符。 ##:常用于把多个参数连接在一起。

条件编译指令

1、#if 指令用于检测后面的常量表达式,如果为真,则编译接下来的代码,直到出现 #else、#elif、#endif为止;否则就不编译。

2、#endif 指令用于终止#if预处理指令。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 由于定义的AXE_TAG宏代表0,#if条件为假,不编译后面的代码,直到#endif,最后只输出
BB。去掉 #define AXE_TAG 0语句,效果也是一样的。
#if AXE_TAG
        printf("AA\n");
#endif
        printf("BB\n");
        
    }
    return 0;
}

3、#ifdef和#ifndef

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define _FBI_WARNING_
 
int main(int argc, const char * argv[]) {
 
#ifdef _FBI_WARNING_
        printf("YES\n");
#endif
        
#ifndef _FBI_WARNING_
        printf("NO\n");
#endif
 
        /*等价于*/
        
#if defined(_FBI_WARNING_)
        printf("YES\n");
#endif
        
#if !defined(_FBI_WARNING_)
        printf("NO\n");
#endif        
    }
    return 0;
}

4、#else指令

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define _FBI_WARNING_
 
int main(int argc, const char * argv[]) {    
#ifdef _FBI_WARNING_
        printf("YES\n");
#else
        printf("NO\n");
#endif
    }
    return 0;
}

5、#elif指令 #elif预处理指令综合了#if和#else指令的作用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define _FBI_WARNING_
 
int main(int argc, const char * argv[]) {
#ifdef _FBI_WARNING_
        printf("YES\n");
#elif FBI_WARNING
        printf("Unknown\n");
#else
        printf("NO\n");
#endif
    }
    return 0;
}

头文件的展开

①#include指令使另外一个文件被编译:预处理器先删除这条指令,并用包含文件的内容替换。这样一个文件被包含10次,那就实际被编译10次。 ②库文件一般用 < > 包含;本地文件一般用 “ ” 包含。 ③文件开头写:#pragma once 可以避免头文件的重复引入。 以上总结,有不足和有误的地方还望指出!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/08/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
讲通C/C++预编译/条件编译指令 #ifdef,#ifndef,#endif,#define,…
预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
看、未来
2020/08/31
5K2
预处理详解(#和##运算符、命名约定、#undef​​、命令行定义​、条件编译、头文件的包含​)
#运算符​ #运算符将宏的一个参数转换为字符串字面量。它仅允许出现在带参数的宏的替换列表中。​ #运算符所执行的操作可以理解为”字符串化“。​ 当我们有一个变量 int a = 10; 的时候,我们想打印出: the value of a is 10 .​ 就可以写:
走在努力路上的自己
2024/01/26
2120
预处理详解(#和##运算符、命名约定、#undef​​、命令行定义​、条件编译、头文件的包含​)
预处理指令、typedef、条件编译、多文件代码
在代码被编译前,预处理器会先处理预处理指令,并根据预处理指令的意义修改C语言源码。
WuShF
2023/03/02
1.3K0
预处理指令、typedef、条件编译、多文件代码
C语言(16)----预处理中的宏以及预处理指令
预处理作为编译的预先准备阶段,其中的宏是一种由预处理器处理的指令或代码片段。宏的基本定义由#define来完成。通常为了区分变量名和函数,宏名通常使用大写字母串来书写。
Skrrapper
2024/06/18
1870
C语言预处理详解
C语言的预处理指令是编程中的一项强大功能,它们在编译器处理代码之前,由预处理器执行。这些指令能够改变源代码的内容,从而提供了一种灵活的代码管理方式。本文将详细介绍C语言中的预处理指令,包括它们的用法、作用和注意事项。
平凡之路.
2024/10/09
1600
C语言预处理详解
#pragma once和条件编译
#pragma once 和 #ifndef 是 C/C++ 中用于防止头文件被多次包含的两种不同的预处理器指令。
薄荷冰
2024/02/07
2860
编码篇-学会小用宏和条件编译
宏定义在C系开发中可以说占有举足轻重的作用。底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行。而在更高层级进行开发时,我们会将更多的重心放在业务逻辑上,似乎对宏的使用和依赖并不多。 编译时编译器会在语义分析认定是宏后,将形参替换为实参,这个过程称为宏的展开。
進无尽
2018/09/12
7840
编码篇-学会小用宏和条件编译
【C 语言】编译过程 分析 ( 预处理 | 编译 | 汇编 | 链接 | 宏定义 | 条件编译 | 编译器指示字 )
间接包含 结构图示 : test_1.c 文件包含 三个头文件, test_1.h 包含的 test_2.h 头文件 与 test_1.c 包含的该头文件相同, 同一个头文件被导入了2次, 因此编译时会报错;
韩曙亮
2023/03/27
1.3K0
【C 语言】编译过程 分析 ( 预处理 | 编译 | 汇编 | 链接 | 宏定义 | 条件编译 | 编译器指示字 )
C进阶:预处理
从.c 文件到 .exe 文件需要经过编译器的翻译,而翻译又分为 编译和链接两个部分
aosei
2024/01/23
1540
C进阶:预处理
条件编译指令:#if,#endif
#if 和 #endif是一组同时使用的,叫做条件编译指令。 #if 与 #define、#include等指令一样是由预处理器这个强大的工具处理的, 预处理器可以在编译前处理c程序。
跋扈洋
2021/02/02
3K0
条件编译指令:#if,#endif
C++中条件编译
C++中常用常用#ifdef,#if和#endif来控制头文件的编译变量检查,控制编译的代码区域。
泽霖
2023/11/26
2170
C语言从入门到实战——预处理详解
C语言预处理是C语言编译过程的一个阶段,它在编译之前对源代码进行一系列的处理操作,包括宏替换、文件包含、条件编译等,最终生成经过预处理的代码,然后再进行编译。
鲜于言悠
2024/03/20
6250
预处理命令 条件编译
一般情况下,源程序中所有的语句都参加编译,但有时也希望根据一定的条件去编译源程序的不同部分,这就是条件编译。
叶茂林
2023/07/28
1720
【C语言】预处理(预编译)详解(下)(C语言最终篇)
   这里的#不是#include和#define前面的那个#,它是一个运算符,这个运算符将宏的⼀个参数转换为字符串字⾯量,它仅允许出现在带参数的宏的替换列表中,#运算符所执⾏的操作可以理解为”字符串化“    在讲解这个运算符之前我们先来看一段代码,如下:
TANGLONG
2024/11/19
2170
【C语言】预处理(预编译)详解(下)(C语言最终篇)
day11嵌入式(2022.1.17)
==================1.gcc编译流程==========================
天天Lotay
2022/12/02
2360
day11嵌入式(2022.1.17)
【C语言】宏定义详解
在C语言中,宏定义是一种强大的预处理器功能,用于在编译之前对代码进行替换和条件编译。宏定义通过预处理器指令进行定义和使用,能够使代码更加灵活和可维护。本文将对C语言中的宏定义进行全面的讲解,包括各种相关的预处理器指令及其用法。
LuckiBit
2024/12/11
1680
【C语言】宏定义详解
程序环境和预处理
在ANSI C的任何一种实现中,存在两个不同的环境 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境,它用于实际执行代码。
绝活蛋炒饭
2024/12/16
870
程序环境和预处理
C语言-预处理(#define、#if...)
1. 区分预处理代码 在C语言程序里,出现的#开头的代码段都属于预处理。 预处理:是在程序编译阶段就执行的代码段。 比如: 包含头文件的的代码 #include <stdio.h> #include <stdlib.h> #include <string.h> 下面列出C语言里常用的预处理代码段: 指令 描述 #define 定义宏 #include 包含一个源代码文件 #undef 取消已定义的宏 #ifdef 如果宏已经定义,则返回真 #ifndef 如果宏没有定义,则返回真 #if 如果给定条件为真,
DS小龙哥
2022/01/07
9460
【C语言篇】编译和链接以及预处理介绍(下篇)
当我们有⼀个变量 int a = 10; 的时候,我们想打印出: the value of a is 10 .
半截诗
2024/10/09
990
【C语言篇】编译和链接以及预处理介绍(下篇)
我与C语言二周目邂逅vlog——7.预处理
C语言预处理是编译过程中的重要组成部分,用于对源代码进行文本替换和修改。预处理发生在编译的前期,通过特定的指令来控制代码的编译行为,最终生成可以交给编译器进行进一步处理的代码。预处理的目的是简化代码编写,提高代码的复用性和可维护性。在本文中,我们将详细讨论C语言中的预处理机制,包括常用的预处理指令、宏定义、文件包含、条件编译等内容。
hope kc
2024/10/19
930
推荐阅读
相关推荐
讲通C/C++预编译/条件编译指令 #ifdef,#ifndef,#endif,#define,…
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文