宏定义正确处理a++

今天c语言有一个题目,是宏实现一个数的平方,但是要正确处理a++这样的参数。

这个我们正常使用还是不会有什么问题,但是一旦参数改为a++的话,这时候就不会得到跟我们理论的正确答案了。

#define   SOMETHING(b)	((b)*(b))

int main(void)
{
	int a=5;
	int b;

	b= SOMETHING (a)*8;

	printf("a = %d b = %d\n",a,b);
}

 

这时我们需要使用一个技巧 tfpeof

#define   SOMETHING(a)	({typeof(a) _b=a;(_b*=_b);})

int main(void)
{
	int a=5;
	int b;

	b= SOMETHING (a++)*8;

	printf("a = %d b = %d\n",a,b);
}

 

以下比较详细的应用转载自
https://www.cnblogs.com/emptyYPen/p/7872604.html


#define mul(a, b)  a*b
a = 2;
b = 3
mul(a+1, b+1);

结果是6。mul(a+1, b+1)被简单的替代成 a+1*b+1 = 2+1*3+1 = 6。这个问题可以用()解决;

 

 

#define MAX(a, b)  (a) > (b)?(a) : (b)
int a = 5;
int b = 2;

MAX( a++, b );
//运行完后a = 7了,一下子自加了两次。

 

宏替代后就是 (a++) > (b)? (a++) : (b);这明显是违反了我们之前想要的。拿什么来拯救宏。要不然宏也太垃圾了。答案是拿变量缓冲来解决这个问题。

 

#define MAX( a, b )  ({  \
    int _a = a;  \
    int _b = b;  \
    (_a) > (_b)? (_a) :(_b); \
  })

int a = 1, b = 3;
int c = MAX( a++, b);

复制代码

完全解决了重复替代可能带来的问题,我先将你的表达式赋值给一个变量,那传入的表达式不就是一个普通的值了吗。然后就可以进行各种操作了。

 

加强该宏 的能力,如果我的a,b不是int类型的呢?

使用typeof()来获取传入的量是什么类型,终于找到一个获取变量类型的操作了。

复制代码

#define MAX( a, b )  ({ \
     typeof (a) _a = a;  \
     typeof (b) _b = b; \
     (_a)  > (_b)? (_a) : (_b); \
  )}

float a = 0.5, b = 1.2;

float c = MAX( a++, b);

复制代码

再进行加强一下,进行数据类型检测是否相同,相同不会出警告,不相同gcc        -Wall  会报警告。我们根据警告来查看我们程序是否有欠妥的地方。

复制代码

#define MAX(a, b)  ({  \
    typeof (a)  _a = a;  \
    typeof (b)  _b = b;  \
    (void)( &_a == &_b);  \
    (_a) > (_b)?(_a) : (_b); \
  })

复制代码

说明:{  ... }程序块不能赋值,所以在外面加个(),就能实现int c = MAX(a, b)了;

          &_a 和&_b做比较,如果他们的指针类型不同,编译器会报警告的,前面加(void)是防止编译器报表达式&_a==&_b没有被应用的警告。到这里就搭建了一个健壮

的宏。

typeof ()也是66666,能用到void*身上吗?

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大智兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值