C语言max宏的进化

C语言max宏的进化

lv1:shit

#define   MAX(a, b)   a > b ? a : b

问题所在不必多言

lv2:角度:参数也可为expr

解:

#define MAX(a, b)   (a) > (b) ? (a) : (b)

bug示例:

#include "stdio.h"

#define MAX(a, b)   (a) > (b) ? (a) : (b)

int main(void)
{
   printf("MAX(a, b) = %d\r\n", 2 + MAX(3, 4));

   return 0;
}

lv3:角度:宏本身为Expr的一部分

解:

#define   MAX(a, b)     ((a) > (b) ? (a) : (b))

bug示例:

#include "stdio.h"

#define MAX(a, b)   (a) > (b) ? (a) : (b)

int main(void)
{
   int a = 2;
   int b = 3;

   printf("MAX(a, b) = %d\r\n", MAX(++a, ++b));

   return 0;
}

lv4:传入参数使用中自身改变的影响

解:

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

bug示例

#include<stdio.h>
#define MAX(a,b)({                         \
                               int _a = a;       \
                               int _b = b;       \
                               _a > _b ? _a : _b; \
                        })

int main(void)
{
   float a = 2.1;
   float b = 3.2;

   printf("MAX(a, b) = %f\r\n", MAX(a, b));

   return 0;
}

lv5:范类型

解:

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

bug示例

#include "stdio.h"

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

int main(void)
{
   float a = 2.1;
   int b = 3.2;

   printf("MAX(a, b) = %f\r\n", MAX(int,a, b));

   return 0;
}

Final:允许跨类型

解:

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

点睛之笔:(void) (&a == &b);,判断地址时编译器首先进行类型判断,一旦类型混用,就可给出warning.

参考:https://www.eet-china.com/mp/a90968.html

posted @ 2022-09-25 15:19  阿莫誒  阅读(90)  评论(0编辑  收藏  举报