C语言宏替换的重复执行机制

20个C语言中常用定义总结 立即下载

ANSI C99标准中预定议了两个宏,__FILE__和__LINE__。这两个宏在断言中很有用
处。但是,这两个宏的类型却不相同:__FILE__展开为一个字符串,__LINE__ 展开为一个
整数。这也就意味着,你可以写出如下代码:

而以下代码却是非法的:

解决这个问题的第一个想法可能是使用“#”宏操作符:

但是这只能产生如下输出

 

 

ISO/IEC 9899:1999 中有这样一段话:

After all parameters in the replacement list have been substituted and # and ## processing has taken place, all placemarker preprocessing tokens are removed. Then, the resulting preprocessing token sequence is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.

 

在所有替换列表中的参数和#及##预处理操作符的置换工作都已经完成,所有占位符都已经被移除之后,其预处理结果将被重新扫描并进
行尽可能多的宏替换。

所以,针对上述问题,我们可以利用宏替换重复执行的特性来间接解决,方案如下:

其宏替换步骤如下:

其结果与以下调用等价:

预处理—— 和函数的区别、的引用场景与注意事项,带副作用的参数引发的问题 阅读详情

相关推荐

【C语言笔记】【定义系列】 重复

【C语言笔记】【定义系列】 重复定义系列内容。用于记录各式各样有用或者没用的定义☺。 定义说明 用于将一个unsigned char类型的数值,以多次重复的形式,返回一个unsigned long类型的数值。 例如unsigned char类型的数值为0x5f,如果使用平台的unsigned long类型长度为32位,那么返回的unsigned long类型的数值为0x5f5f5f5f。 该定义来自linux kernel 5.10。 实现代码 #define REPEAT_BYTE(x) (

1270

C/C++_定义多次重复定义

$MS编译器下多次重复定义以最后的作为标准 #include using namespace std; #define MAX 5 #define MAX 4 #define MAX 3 int main() { printf("%d\n", MAX); return 0; }

迎难而上 1万+

C中的应用

写好C语言,漂亮的定义很重要,使用定义可以防止出错,提高可移植性,可读性,方便性 等等。下面列举一些成熟软件中常用得定义。。。。。。1,防止一个头文件被重复包含#ifndef COMDEF_H#define COMDEF_H//头文件内容#endif2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。typedef unsigned char      b

cancer1617的专栏 1725

深入理解 C 语言预处理:从源文件到可执行程序的关键步骤

源程序文件首先经历预处理阶段,接着进入编译环节,最后通过链接步骤,才最终成为可执行程序文件。这每一步都有着独特且不可或缺的作用,而预处理就像是为后续的编译和链接搭建稳固的基石。

qq_37077760的博客 922

C语言宏替换定义高级用法

1.无参数:简化常量与重复代码#define 名 替换文本核心用途:定义常量:代替const,更灵活(无类型检查,编译前替换)#define PI3.14159261024//缓冲区大小#define ERR_MSG "内存分配失败"注意事项:替换文本末尾不要加多余分号,否则会导致逻辑错误,如2.带参数:实现"函数"#define 名(参数) 替换文本核心优势:比普通函数执行快(无函数调用开销,直接替换)示例:1.求两数最大值(a) :(b))(a) :(b))(a) :(b))

2502_93780134的博客 1024

17 C 语言进阶必看:从宏替换避坑到函数用法,不定参数模拟实现一次搞定

本文详细介绍了C语言预处理的相关知识,主要包括预定义符号和定义的使用。预定义符号如__FILE__、__LINE__等可在编译时获取文件信息;定义(#define)用于文本替换,可定义常量、带参数和复杂表达式。文章重点讲解了宏替换规则、与函数的区别、#和##运算符的使用技巧,以及可变参数的实现方法。通过大量示例说明了定义中的常见问题和注意事项,如括号使用、参数类型无关性、字符串化和符号拼接等特性,帮助开发者正确使用预处理功能提高代码效率。

2301_76755408的博客 1308

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

宏替换、文件编译和头文件的展开 程序执行的几个步骤: 1.预处理: ①将头文件展开 ②宏替换 ③条件编译 ④去掉注释 2.编译: ①语义语法纠错 ②将.c文件编译成汇编语言 3.汇编:将汇编语言变成二进制机器语言 4.链接:将所有的目标文件和依赖的库文件进行汇总,得到最终的可执行程序 以下开发工程中经常用到的部分预处理指令: #define <#macro#> // 定义...

海盗船长y的博客 1372

预编译阶段错误频发?,一文搞定C语言宏替换的隐藏雷区

掌握C语言中预编译的调试技巧,有效定位宏替换中的隐藏问题。适用于复杂条件编译、多层嵌套等场景,通过#、##操作符解析与gcc -E指令展开,快速排查语法错误与逻辑陷阱,提升代码稳定性,值得收藏。

CodeVibe的博客 780

c语言程序的预处理

程序的翻译环境 程序的执行环境 详解C语言程序的编译+链接 预定义符号 预处理指令#define 和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令#include 预处理指令#undef 条件编译 程序的翻译环境 程序的翻译环境和执行环境 在任何c的实现中都存在两种不同的环境 1.翻译环境就是在这环境中源代码被转换为可执行的机器指令 2.执行环境就是实际执行代码 程序的执行环境 3.运行环境 1).程序必须载入内存中,在有操作系统的环境中,这一般由操作系统完成, 在独立的

m0_61567378的博客 3028

深入解析C语言中的`定义`:从底层原理到高级应用

定义(Macro Definition)是C语言预处理器(Preprocessor)提供的一个功能,允许程序员定义常量、函数式以及复杂的代码片段。定义的主要作用是在编译前对源代码进行文本替换,从而简化代码编写、提高代码可读性和可维护性。常量:用于定义常量值,避免在代码中直接使用硬编码的数值。函数式:用于定义类似函数的功能,但比普通函数更高效,因为定义在编译前被展开为内联代码,避免了函数调用的开销。复杂:用于定义复杂的代码片段,如条件编译、调试信息等。定义的语法非常简单,使用。

极客代码 1455

C语言中预编译/预处理的使用

C预编译使用相关学习记录

weixin_44475356的博客 1280

C语言终极解密:从 .c 到 .exe 的底层涅槃与预处理魔法

本文是C语言硬核剖析系列的收官之作,深入解析了C程序从源代码到可执行文件的完整编译过程。

有时work,经常BUG,总是DeBug 890

[C语言]:预编译指令

define是预编译中最常用的指令,用于定义常量或带参数的,本质是字符串替换,替换过程发生在预编译阶段,不占用运行时资源。直接定义一个常量符号,替换时仅做字符串替换,无需加分号(否则会导致额外语法问题)。2// 定义常量TWO,值为2TWO // 嵌套使用已定义的// 预编译后替换为 int x = 2;// 输出2x = FOUR;// 预编译后替换为 x = 2*2;// 输出4return 0;注意:定义常量时末尾不要加;,否则会出现类似x = 2;;的语法冗余。

alwaysAlearner的博客 696

超详细的C进阶教程!(七)C语言预处理

作者的码云地址:https://gitee.com/dongtiao-xiewei 后续作者会更新力扣的每日一题系列,原代码会全部上传码云,推荐关注哦,笔芯~ 还像更深入地了解c语言?快来订阅作者的c语言进阶专栏!作者承诺本系列不会TJ!预计更新:指针,字符串处理,内存管理,结构体,预处理等等 感谢朋友们的支持,我们这个系列今天终于完结啦! 我们一直以来写的代码,本质其实都是以.c文件为后缀名的文本文件,例如我们随便以记事本形式点来一个.c后缀的文件 点开我们看到,就是我们熟悉的代码样式 但这就有.

dtxew love c++ 1万+

C语言预处理详解

2. #define定义常量。

CSQCSQCC的博客 941

C语言编译流程分析

对C语言编译流程的一个简单总结

qq_45668408的博客 659

C语言--预处理详解

define 机制包括了⼀个规定,允许把参数替换到文本中,这种实现通常称为(macro)或定义(define macro)这个定义的也是直接替换的其中的 parament-list 是⼀个由逗号隔开的符号表,它们可能出现在stuff中。注意:参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的⼀部分用于对数值表达式进行求值的定义都应该加上括号,避免在使用时由于参数中的操作符或之外邻近操作符之间不可预料的相互作用。

2301_79814410的博客 931

94.【C语言】解析预处理(2)

(a) : (b) )中a出现两次),如果参数带有副作用,那么你在使用这个的时候就可能出现危险,导致不可预测的后果。2.再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号,MAX(x,10)被替换为( (x) > (10)?1.首先对参数进行检查,MAX(x,NUM)的NUM首先被替换,之后为MAX(x,10);2.参数类型上:函数需要指定参数的类型,而的参数和类型无关(这里体现出的缺点,不严谨)执行(x++) > (y++)后, 还要执行y++,这里y加了两次,为副作用的体现。

zhangcoder的博客 记录学习轨迹~ 1211
上一篇: Icesword驱动部分分析
pmliming
博客等级 码龄26年 1粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值