#define宏定义详解

本文主要对宏定义相关进阶的用法展开描述

常用宏定义用法

经常使用C编程的话都会一些基本的宏定义替换,例如变量、关键字、函数等,示例如下:

#define TOTAL_NUM 1000
#define GLOBAL_MOCK_VERIFY GlobalMockObject::verify();
#define CHECK_FUN_RET_INT(fun, val) do {int ret = fun; if (val == ret) {;}} while(0)

续行操作

我们经常是会遇到编写一个宏定义全部写在一行内太长,可读性也非常差,这个时候需要换行就可以用到我们的续行操作符了

#define RETURN_IF_RET_FAILURE(expr) \
{if(-1 == expr) {SYSLOG_NOTICE; return FAILURE;}}

#define MBQ_CAT_MEM(data, len)              \
  do {                                      \
    nwrite += len;                          \
    if (nwrite > sz) {                      \
      return -1;                            \
    } else {                                \
      memcpy(buf, data, len);               \
      buf += len;                           \
    }                                       \
  } while (0)

#define 定义宏

#define 机制包括了一个规定,允许将参数替换文本中,这种实现通常被称为宏(macro)定义宏(define macro)

#define SQUARE( x ) ((x) * (x))

也许会有小伙伴有疑问,为啥后面的x相乘要加这么多括号,看起来眼花缭乱的,去掉括号不是简单明了编写方便嘛?这就涉及到了定义宏的隐患问题啦,我们分内部隐患和外部隐患来解释一下

内部隐患

#define SQUARE( x ) x * x

int main (void) {
    int val = 5;
    printf("result is %d\n", SQUARE(val + 1)); 
    return 1;
}

这里printf打印的值是36吗

显然不是,宏替换文本时,x 被替换成5 + 1,所以这段代码应该展开如下

printf("result is %d\n", 5 + 1 * 5 + 1); 

打印输出应该为11

所以,参数内部加括号是必要的

外部隐患

内部隐患解决了,让我们再来看看外部隐患:

#define DOUBLE( x ) (x) + (x)

int main (void) {
    int val = 5;
    printf("result is %d\n", 10 * DOUBLE(val)); 
    return 1;
}

这里printf打印的值是不是100呢?

显然也不是,让我们先将其展开

printf("result is %d\n", 10 * 5 + 5); 

打印输出应该为55

所以,最外层加括号也是必要的

括号的使用

临时追加这一栏,因为今天遇到一件非常有意思的事,一位同事将他本地写好的代码给我拿去跑编译,其中有个宏定义编译一直在报错,起初我也是没看出来哪里有问题,大家第一眼能识别出来吗

#define GET_EADDR(func, addr) { (((func) & 0xFF) << 16) | ((addr) & 0XFFFF) }

乍一眼看是不是天衣无缝?该加的括号确实也加了,内部的语法也没有问题。

其实问题就出在这个宏定义是定义了一则运算,将func和addr两个入参通过位运算重构合并成一个数值,这个宏返回这个数值,它并不是单独一条语句,但是此处却用到了{},那么这段宏基本单位就是语句了,让我们看看用法就明白了

int result = GET_ADDR(0X10, 0X1001);

#的使用

使用 “#” 可以将宏的参数变为对应的字符串,示例如下:

#define PRINT(FORMAT, VALUE)\
		printf("the value of " #VALUE " is "FORMAT "\n", VALUE);

int main (void) {
    int i = 10;
	PRINT("%d", i+3);
    return 1;
}

此处打印应是the value of i + 3  is 13

## 的使用

## 可以把位于它两边的符号合成一个符号,它允许宏定义从分离的文本片段创建标识符

#define ADD_TO_SUM(sum, num)\
    sum##num += num;

ADD_TO_SUM(5, 10);        //展开即是sum5 += 10;

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值