C语言基础-define的用法

2023-12-17 22:42:01

前言

define对于用过C语言的同学应该都不陌生,常用的就是宏定义,可以用作开关,也可以用作参数定义。实际除了简单的参数定义外,还有一些特殊的符号,可以实现一些“骚操作”

一般用法

宏开关

当我们想用一个宏定义来控制一段代码是否参与编译,也可以说一个功能是否启用(功能对应的代码都加上了对应的宏定义)可以使用宏开关的方式实现

示例如下:我们定义一个LED_Ctrl的功能

#define LED_Ctrl

#ifdef LED_Ctrl
 IoHwAb_Led_Ctrl(Led0,STD_ON);
....
#endif

通过定义和取消定义该宏定义,即可实现该功能是否启用,在项目前期调试过程中,会经常用到。量产交付时,应尽可能减少该类宏定义。

参数定义

通过宏定义替换参数,可以实现在多个地方使用同一个参数时,方便修改。

示例如下:

# define AdcHwUnit_NUM                      ( 3U)

  for(Index = 0; Index < AdcHwUnit_NUM; Index++)
  {
     ....
  }

宏函数

使用宏函数可以实现一些判断逻辑或计算公式。常用的如MAX,MIN,ABS宏函数

#define MAX(a,b) (a>b)?a:b
...
 max=MAX(x,y);

宏函数在MISRA中建议不要使用。具体可以参考规范。

特殊用法

连接操作符##

##表示连接,在宏定义中,使用##可以实现传递参数,而实现不同的函数定义,在RH850P1HC的MCAL中有类似的定义:

#define DIO_ENTER_CRITICAL_SECTION(Exclusive_Area) \
                                   SchM_Enter_Dio_##Exclusive_Area()
                                   
      DIO_ENTER_CRITICAL_SECTION(DIO_REGISTER_PROTECTION);

最终函数实现:SchM_Enter_Dio_DIO_REGISTER_PROTECTION();

调用函数时传递的名称不同,最终出来的函数也不一样

还有一种用法,可以改变输入的参数,实现不同的定义输入:

例如,我们在MCAL中定义了两个Sequence,一个TEST_One_SpiSequence,一个TEST_Two_SpiSequence,通过如下宏定义:

#define Spi_SyncTransmit_Abstract(name)               Spi_SyncTransmit(TEST_##name##_SpiSequence)

我们调用Spi_SyncTransmit_Abstract(One);时,最终发送的就是TEST_One_SpiSequence
当调用Spi_SyncTransmit_Abstract(Two);时,发送的就是TEST_Two_SpiSequence

(\) 续行操作符

当宏定义太长,需要换行时,就需要用到\,该符号应该在头文件中很常见。

#define DIO_DBTOC_VALUE ((((uint32)DIO_VENDOR_ID) << (uint32)22) | \
                         (((uint32)DIO_MODULE_ID) << (uint32)14) | \
                         (((uint32)DIO_SW_MAJOR_VERSION) << (uint32)8) | \
                         (((uint32)DIO_SW_MINOR_VERSION) << (uint32)3))

注意:最后一行不要加续行符

#@ 字符化操作符

"#@"是给参数加上单引号。这个在嵌入式中应该用的比较少

#define TOCHAR(a) #@a   /* TOCHAR(1) => '1' */

文章来源:https://blog.csdn.net/weixin_49000276/article/details/135050549
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。