代码改变世界

宏定义值a++

2017-11-21 12:29  小白很我  阅读(955)  评论(0编辑  收藏  举报
#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*身上吗?