使用带##连接符的参数宏简化代码,但循环体变量向其传参是无效的

使用带##连接符的参数宏简化代码,但循环体变量向其传参是无效的

1 简介:背景与目的

近期QB在做嵌入式软件的工作,看这一大坨代码时强迫症发作:

 	BspTimPwmSetCompareValue(&DRV_M1_TIM,  DRV_M1_CHANNEL,  2000 );
	BspTimPwmSetCompareValue(&DRV_M2_TIM,  DRV_M2_CHANNEL,  3500 );
	BspTimPwmSetCompareValue(&DRV_M3_TIM,  DRV_M3_CHANNEL,  5000 );
	...
	BspTimPwmSetCompareValue(&DRV_M12_TIM, DRV_M12_CHANNEL, 18500);

不够简化,通过使用宏能够美化一下代码。不过还是需要直接传递实际数值,不可以用循环传递变换的值,具体看下方的第三部分。

2 参数宏中#和##的使用

关于宏的#和##知识,参考文章为:
link1.
link2.

在此处使用##的连接功能,简洁地替换掉DRV_TIM和DRV_CHANNEL等参数。

2.1 代码应用

探索一下实际应用,简单的案例为:

#include <stdio.h>
#define CNNCT(I) a_##I
#define PUT(C) #C"\n"
int main()
{
	int a_1=1;
	int a_2=2;
	printf("%d\n",CNNCT(1));
	printf("%d\n",CNNCT(2));
	printf(PUT(CNNCT(1)));
	printf(PUT(CNNCT(2)));
}

输出为:

1
2
CNNCT(1)
CNNCT(2)

同理,对于简介部分的代码,可以改写为:

#define PWM(i) BspTimPwmSetCompareValue(&DRV_M##i##_TIM, DRV_M##i##_CHANNEL, 1500 * i + 500);
PWM(1);
PWM(2);
PWM(12);

2.2 无法使用循环加##宏继续简化

简介代码改写后,应用12次就要写12行代码,很自然地会想到使用循环。但是如果像下面这样循环,会报错:

// qbWarning: Wrong Code!
for(int i=1; i<=12; i++)
{
	PWM(i);
}

错误提示为:DRV_Mi_TIM和DRV_Mi_CHANNEL未定义。

出现该错误的原因是,宏定义是一种简单的文本替换,而且##也只是简单的文本连接,所以PWM(i)中的i不会被展开为数字,而是直接替换为i。
这一点是由宏和##的工作原理决定的,即使用函数或者变量中转,只要不是实际的数值,也就只是从Mi变成Ma、Mb之类的区别罢了。

#include <stdio.h>
#define CNNCT(I) a_##I
#define PUT(C) #C"\n"
int GetNum(int i)
{
	return i;
}
int main()
{
	int a_1=1;
	int a_2=2;
	for(int i=1; i<=2; i++)
	{
		int x;
		x = GetNum(i);
		printf(CNNCT(x));
	}
}

结果:main.c:2:18: error: ‘a_x’ undeclared (first use in this function); did you mean ‘a_2’? 2 | #define CNNCT(I) a_##I

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值