abs int 宏定义_C/C++编程笔记:宏的妙用(一切为了偷懒)

总结出自己经常重复的工作,抽象简化它们,按照适合自己思维方式,整合成我们自己需要的。
偷懒就是尽可能的少写代码,实现我们需要的效果。
前两篇究其根本也是为了能够尽可能的少写代码,从而节省时间。一切为了偷懒 看似调侃,其实就是我的本心。** (^▽^) **
所以开始我的偷懒之旅吧!

52c2e570a1e2f306785f2dcdc270ff40.png

宏的特性

宏的原样展开特性,对于才接触或者不怎么喜欢使用宏的人来说,宏一般用来定义常量或者类型,仅此而已,比如:

#define  PI  3.1415926#define  unsigned char  uchar

或者实现一些简单的函数功能,因为没有类型,有时候类似模板一样,可以输入使用不同类型的参数,比如:

#define  add(x,y)  (x+y)#define  sub(x,y)  (x-y)#define  mul(x,y)  (x*y)#define  dev(x,y)  (x/y)

我的偷懒方式

1、指针、返回值检查

平常判断指针,都会类似如下方式:

int ret = 3;int *ptr = &ret;if (ret == -1)    return; if (ptr == NULL)    return; 

可能带打印且有返回值,便于快速分析:

int ret = 3;int *ptr = &ret;if (ret == -1){    std::cout << "ret:" << ret << std::endl;    return; }if (ptr == NULL){    std::cout << "ptr:" << ptr << std::endl;    return false;  // 或者 -1}

可以如下实现:

#define check(var, value, ...)     if (var == value) {        logs(var);        return __VA_ARGS__;    }

使用方式如下:

void test1() // 无返回值{    int ret = 3;    int *ptr = &ret;    check(ret , -1);    check(ptr, NULL);}int test2() // 有返回值{    int ret = 3;    int *ptr = &ret;    check(ret, -1, 0);    check(ptr, NULL, false);}

2、指针释放销毁

指针内存释放,一般用自带的 delete 或者有自己的释放函数,假设如 free(),则方式如下:

xxx *ptr = new xxx;...if (ptr != NULL){    delete ptr;  // or  free(ptr);    ptr = 0;}

则可简单如下定义:

#define delptr(ptr)             if (ptr) {delete ptr; ptr = 0;}#define freeptr(fun, ptr)       if (ptr) {fun(ptr); ptr = 0;}

对于集合型指针,则可直接如下定义:

#define delptrlist(list)       for (int i = 0; i < list.size(); i++) delete list[i]; list.clear();#define delptrset(list, type)  foreach (type p, list) delptr(p); list.clear();#define delptrset11(list)      foreach (auto p, list) delptr(p); list.clear();   // 版本 >= c++11 

3、单实例类

对于类中的一种特殊设计模式,有时候仅仅需要一个对象实例即可,可以直接简单实现如下:

#define Singleton(ClassName) static ClassName &instance() {      static ClassName *m_instance = 0;    if (m_instance == 0)        m_instance = new ClassName;    return *m_instance;}

在对需要单实例的类加上如下设置即可:

class CTest{public:    Singleton(CTest)  // 添加单实例宏    ~CTest();    void xxxx();    void yyyy();private:    CTest();};

使用方式如下:

CTest::instance().xxxx();   CTest::instance().yyyy();

更简洁的使用形式如下:

#define ctest CTest::instance()ctest.xxxx();ctest.yyyy();

4、用于数组校验

对于串口、网络数据收发时,常有一些数据计算校验计算,有的是和、有的是亦或,可以简单归纳如下:

#define calc(dat, len, opt) ({     uchar val = dat[0];     for (int i = 1; i < len; i++)         val opt dat[i];     val; })

使用方式如下:

uchar dat[30];...uchar sum = calc(dat, 30, +=);uchar xor = calc(dat, 30, ^=);

如果是集合,向量等形式,可以修改如下:

#define calcset(arr, opt) ({     uchar val = arr[0];     for (int i = 1; i < arr.size(); i++)         val opt arr[i];     val; })

使用方式如下:

std::veroct  array;...uchar sum = calc(array, +=);uchar xor = calc(array, ^=);

对于非 uchar 类型数据,小伙伴们是不是可以自己很容易扩展了呢!?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值