本帖最后由 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的使用技巧和方法,欢迎来贴分享和讨论!
让我们一起进步,变的更加优秀。
|