C/C++中#define的妙用分享

 更新时间:2023年02月23日 08:43:52   作者:西西弗Sisyphus  
本文主要介绍了C++/C关于#define的一些妙用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1.数值类型输出易读的字符串形式

例如使用enum定义一些错误值,想要将数值类型的错误,输出易读的字符串形式

重要的一句代码

#define MAKE_PAIR(val) std::make_pair(val, #val)

可以看到 #val,宏定义中的传入参数名val 转换成字符串,就像用一对双引号包含起来的val

完整实现代码如下

#include <iostream>
#include <cinttypes>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
using namespace std;

typedef enum {
    ACAMERA_OK = 0,
    ACAMERA_ERROR_BASE                  = -10000,
    ACAMERA_ERROR_UNKNOWN               = ACAMERA_ERROR_BASE,
    ACAMERA_ERROR_INVALID_PARAMETER     = ACAMERA_ERROR_BASE - 1,
    ACAMERA_ERROR_CAMERA_DISCONNECTED   = ACAMERA_ERROR_BASE - 2,

} camera_status_t;



#define UKNOWN_TAG "UNKNOW_TAG"
#define MAKE_PAIR(val) std::make_pair(val, #val)
template <typename T>
const char* GetPairStr(T key, std::vector<std::pair<T, const char*>>& store) {
  typedef typename std::vector<std::pair<T, const char*>>::iterator iterator;
  for (iterator it = store.begin(); it != store.end(); ++it) {
    if (it->first == key) {
      return it->second;
    }
  }
  //LOGW("(%#08x) : UNKNOWN_TAG for %s", key, typeid(store[0].first).name());
  return UKNOWN_TAG;
}
using ERROR_PAIR = std::pair<camera_status_t, const char*>;
static std::vector<ERROR_PAIR> errorInfo{
    MAKE_PAIR(ACAMERA_OK),
    MAKE_PAIR(ACAMERA_ERROR_UNKNOWN),
    MAKE_PAIR(ACAMERA_ERROR_INVALID_PARAMETER),
    MAKE_PAIR(ACAMERA_ERROR_CAMERA_DISCONNECTED),
};
const char* GetErrorStr(camera_status_t err) {
  return GetPairStr<camera_status_t>(err, errorInfo);
}


int main()
{
    std::cout<<GetErrorStr(ACAMERA_ERROR_INVALID_PARAMETER)<<std::endl;
    return 0;
}

输出

ACAMERA_ERROR_INVALID_PARAMETER

2.易记的简化调用

例如有两个函数

camera_status_t ACameraManager_A()
{
   std::cout<<"A"<<std::endl;
   return ACAMERA_OK;
}

camera_status_t ACameraManager_B()
{
   std::cout<<"B"<<std::endl;
   return ACAMERA_OK;
}

这两个函数很长,函数名前缀相同

想要易记的简化调用

例如

CALL_MGR(A()); //实际调用ACameraManager_A()
CALL_MGR(B()); //实际调用ACameraManager_B()
#define CALL_CAMERA(func)                                             \
  {                                                                   \
    camera_status_t status = func;                                    \
    std::cout<<GetErrorStr(status)<<std::endl;                        \
  }
#define CALL_MGR(func) CALL_CAMERA(ACameraManager_##func)

#define 后面的 \ 表示下一行继续写宏定义。

两个#号 ## 表示连接操作符。 CALL_MGR(A());通过 ACameraManager_##func 变成了ACameraManager_A

实现完整代码如下

#include <iostream>
#include <cinttypes>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
#include <assert.h>
using namespace std;

typedef enum {
    ACAMERA_OK = 0,
    ACAMERA_ERROR_BASE                  = -10000,
    ACAMERA_ERROR_UNKNOWN               = ACAMERA_ERROR_BASE,
    ACAMERA_ERROR_INVALID_PARAMETER     = ACAMERA_ERROR_BASE - 1,
    ACAMERA_ERROR_CAMERA_DISCONNECTED   = ACAMERA_ERROR_BASE - 2,

} camera_status_t;



#define UKNOWN_TAG "UNKNOW_TAG"
#define MAKE_PAIR(val) std::make_pair(val, #val)
template <typename T>
const char* GetPairStr(T key, std::vector<std::pair<T, const char*>>& store) {
  typedef typename std::vector<std::pair<T, const char*>>::iterator iterator;
  for (iterator it = store.begin(); it != store.end(); ++it) {
    if (it->first == key) {
      return it->second;
    }
  }
  //LOGW("(%#08x) : UNKNOWN_TAG for %s", key, typeid(store[0].first).name());
  return UKNOWN_TAG;
}
using ERROR_PAIR = std::pair<camera_status_t, const char*>;
static std::vector<ERROR_PAIR> errorInfo{
    MAKE_PAIR(ACAMERA_OK),
    MAKE_PAIR(ACAMERA_ERROR_UNKNOWN),
    MAKE_PAIR(ACAMERA_ERROR_INVALID_PARAMETER),
    MAKE_PAIR(ACAMERA_ERROR_CAMERA_DISCONNECTED),
};
const char* GetErrorStr(camera_status_t err) {
  return GetPairStr<camera_status_t>(err, errorInfo);
}


camera_status_t ACameraManager_A()
{
   std::cout<<"A"<<std::endl;
   return ACAMERA_OK;
}
camera_status_t ACameraManager_B()
{
   std::cout<<"B"<<std::endl;
   return ACAMERA_OK;
}
#define CALL_CAMERA(func)                                             \
  {                                                                   \
    camera_status_t status = func;                                    \
    std::cout<<GetErrorStr(status)<<std::endl;                        \
  }
#define CALL_MGR(func) CALL_CAMERA(ACameraManager_##func)
int main()
{

    CALL_MGR(A());
    CALL_MGR(B());
    return 0;
}

输出

A
ACAMERA_OK
B
ACAMERA_OK

以上代码应用在google的ndk camera代码中

到此这篇关于C/C++中#define的妙用分享的文章就介绍到这了,更多相关C++ #define内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 探讨:将两个链表非降序合并为一个链表并依然有序的实现方法

    探讨:将两个链表非降序合并为一个链表并依然有序的实现方法

    本篇文章是对将两个链表非降序合并为一个链表并依然有序的实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言实现输入ascii码,输出对应的字符方式

    C语言实现输入ascii码,输出对应的字符方式

    这篇文章主要介绍了C语言实现输入ascii码,输出对应的字符方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • C语言宏定义容易认不清的盲区梳理

    C语言宏定义容易认不清的盲区梳理

    宏定义是C提供的三种预处理(宏定义、文件包含、条件编译)的其中一种,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率
    2022-09-09
  • C++实现寻找最低公共父节点的方法

    C++实现寻找最低公共父节点的方法

    这篇文章主要介绍了C++实现寻找最低公共父节点的方法,是数据结构中二叉树的一个经典算法,有一定的借鉴价值,需要的朋友可以参考下
    2014-09-09
  • C语言实现2048游戏(ege图形库版)

    C语言实现2048游戏(ege图形库版)

    这篇文章主要为大家详细介绍了C语言实现2048游戏,ege图形库版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • ACE反应器(Reactor)模式的深入分析

    ACE反应器(Reactor)模式的深入分析

    本篇文章是对ACE反应器(Reactor)模式进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言实现排雷游戏(多文件)

    C语言实现排雷游戏(多文件)

    这篇文章主要为大家详细介绍了C语言实现排雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • C++读取到回车换行符问题处理

    C++读取到回车换行符问题处理

    有一个程序只需对输入的一行字符一个个进行独立判断,C的话用getchar()就好了,但是用C++的时候发现CIN似乎不接受回车符……搜索解决方法的时候很多人都建议将getline,然后处理数组或者定义一个流什么的,但是这样一行可能很长,要占用很多空间。有没有别的办法?
    2015-08-08
  • QT使用QComBox和QLineEdit实现模糊查询功能

    QT使用QComBox和QLineEdit实现模糊查询功能

    模糊查询是指根据用户输入的文本,在下拉框的选项中进行模糊匹配,并动态地显示匹配的选项,本文将使用QComBox和QLineEdit实现模糊查询功能,需要的可以参考下
    2023-11-11
  • C语言编写多功能日历

    C语言编写多功能日历

    之前看到本站给大家分享了一则C语言实现的简单日历,就手痒了,也想自己写一个,既然有简单了,那咱写个稍微复杂点的,多功能的吧。呵呵,玩笑玩笑
    2015-03-03

最新评论