打印
[技术讨论]

【C语言实战经验3】你用过宏定义#define的哪些功能呢?

[复制链接]
112|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dffzh|  楼主 | 2025-5-2 21:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dffzh 于 2025-5-3 10:22 编辑

#申请原创#
@21小跑堂

从事软件开发的朋友们应该对C语言的宏定义#define的功能和应用都不陌生,因为#define使用起来即简单,功能又强大,无论是代码的可维护性、可读性,或者是健壮性,都可以让你的代码层次明显的上一个台阶。
在阅读这篇文章之前,你可以先思考一下用过#define的哪些功能以及知道哪些功能?然后再看这边文章。
下面作者就以自己的实际应用经验与大家分享一下#define的主要功能。

1、最简单的也是最常用的功能:直接定义一个常量
对于程序里有意义的或者使用次数较多的数值,如果你是直接以数字的方式呈现到代码里面,那就赶紧用#define来声明一下吧(当然你也可以用枚举操作),别被你的软件Boss看到。这里就简单举两个例子:
建议:
后面的数值都加上括号,养成好习惯,不然你早晚会踩坑。

2、声明一个宏用作开关选择功能(条件编译)
有时我们会用不同的代码方式实现同一个功能,或者因为硬件调测我们会临时增加测试代码等等,这个时候你可以用代码备份来实现或者直接用宏定义来操作:
此时的宏定义其实就相当于是一个开关选择功能,程序会根据你是否定义了该宏来选择合适的代码执行。在很多MCU的固件库代码里,应该有不少这样的操作方式。
这样操作后,只要你在相关代码位置加上该宏定义,后期修改时,只要操作定义或不定义这个宏即可,而且不用担心会出现漏改和错改等问题。

3、声明一个宏函数功能
宏定义可以用来声明一个函数,称之为宏函数,由于宏函数对入参的数据类型没有要求,所以其应用场景还是比较广的,受大家青睐。基本格式大概如下:
#define 函数名(参数1,参数2,...参数n)  (函数体)
以下声明了一个大家常见的计算两数之和的宏函数:
以下声明了一个根据模式不同选择计算输出数据的宏函数(实际应用):
备注:
宏函数和普通函数的差别还是比较大的,有兴趣的可以研究一下,实际应用时根据自身需求进行选择。

4、声明一个递归宏功能(我这么称呼的)
有些宏定义的值会随其他宏定义的值而改变,有时候甚至是多层改变,此时我们就可以直接将宏定义的名称作为另一个宏的值来操作:
PARAMETER_VALUE_1的值随PARAMETER_VALUE_0而改变;
PARAMETER_VALUE_2的值随PARAMETER_VALUE_1而改变;
这样,任何时候只要操作一次修改即可。
以下是实际项目上存储数据的EEPROM地址的宏定义:
需要修改时,只要修改EEPROM1_START_ADDR起始地址即可,特别方便。
其实在MCU固件库的代码里,大量使用了这样的操作:

5、避免头文件被重复包含
一般在头文件里,都有类似下面的宏定义代码:
其作用就是通过宏定义的方式防止头文件被多次重复引入。

6、用来初始化数组
最近看到宏的一种应用,即用来初始化数组:
你这么用过吗?

7、用作连接操作符
之前在一篇文章里见过宏用作连接操作符的应用:
这种在大量操作字符串的代码里应该有用武之地。

虽然宏定义使用起来比较方便,但是凡事有利有弊,以下的注意事项要牢记:
宏定义只是文本替换,即不会进行类型检查;
宏定义在定义位置之后全局有效;
宏定义展开后的易调试性可能会下降,即编码器看到的代码与源码不一样。

以上作者主要介绍了#define的七种应用功能及其注意事项,如果你合理且有度地使用#define,可以简化代码,但是实际应用时需要谨慎,避免滥用导致出现问题。

如果你有更多关于宏定义#define的使用技巧和方法,欢迎来贴分享和讨论!

让我们一起进步,变的更加优秀。

249096814c33bb2751.png (65.75 KB )

249096814c33bb2751.png

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

202

帖子

3

粉丝