优雅的c语言宏定义比较大小

写一个宏定义,返回两个数中较大的一个。相信绝大部分同学都能闭着眼睛写出来,但闭着眼睛写的真的对吗,怎么样写可以做到极致的优雅,适用几乎所有应用场景。

幼儿园写法:

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

        但是有些不听话的小朋友在使用这个宏的时候可能会这样写:

#include <stdio.h>

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

int main (int argc, char *argv[])
{
        printf("%d", MAX(4&4, 2&4));
        return 0;
}

        运行结果:

0

这就出错了,这是由于运算符优先级导致了运行结果偏离预期,&的优先级小于<。

小学写法:

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

也有一些聪明的小学生,会写到:

#include <stdio.h>

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

int main (int argc, char *argv[])
{
        printf("%d\n", 1+MAX(3, 2));
        return 0;
}

运行结果是3!这也是因为运算符优先级引发的问题,+的优先级要大于>。

初中写法:

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

这样写很好地规避了运算符优先级带来的问题,但它还不是完美的,请看:

#include <stdio.h>

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

int main (int argc, char *argv[])
{
        int a = 3, b=4;
        printf("%d\n", 1+MAX(a++, b++));
        return 0;
}

运行结果是6!这是因为在比较的过程中,变量自身发生了变化,虽然编程规范一般不允许这样传递参数,但到底有没有办法规避这些隐患呢。

高中写法:

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

这个写法已经能规避很多问题了,但很明显的问题是,它只适用于int类型数据的比较。于是又有了

本科写法:

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

这样就可以支持多种数据类型了。但是它要用到3个“参数”,我需要比较两个数的大小,为什么要我传递3个“参数”呢。

硕士写法:

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

typeof在gun c上是可以支持的,它可以自动获取参数类型。

(void)(&_a == &_b);这条语句则可以用来提示传入参数类型不一致的警告。编译的时候就可以提示警告。

到这里,比较大小的宏定义已经足够优雅了。也许你会觉得写个宏定义需要这么复杂吗,别急,不妨再看看《内联函数》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值