Abstract

之前写了一个非常mini的log库(也不算库把,自己瞎jb写的),里面几乎都是宏的实现。这里打算趁热打铁,把自己知道的几下子都贴出来,后续如果有新的收获会更新这个博文。

文笔拙劣,主要是给自己做个提醒。

1. 运行时检测大小端

一目了然,不做解释。

#define __ENDIAN() ({ \
short _a = 0x1234; \
*((char*)&_a) == 0x12 ? 1 : 0; \
})
#define big_endian() (__ENDIAN() == 1)
#define little_endian() (__ENDIAN() == 0)

当然还有另一种方式去确定字节序。下面是编译时确定字节序的方式。

只要通过引入头文件<endian.h>便可以在编译时通过宏判断字节序了。参考 ‘/usr/include/linux/tcp.h’ 你会发现另一种写法(自己去看下)。

#if __BYTE_ORDER == __LITTLE_ENDIAN
// do_sth();
#elif __BYTE_ORDER == __BIG_ENDIAN
// do_sth();
#else
#error "Unknown byte order"
#endif

2. max函数与min函数

max与min函数是最常用的。我们可以有很多方式去实现它,宏,inline,函数等。

由于这两个函数都很小,一般不建议

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

3. SDK 中的函数名拼接

#include <stdio.h>

#define test(__DOC, args) __SDK_##__DOC##_TEST(args)
void __SDK_V1_TEST(int a) {
fprintf (stdout, "version %d\n", a);
return;
} void __SDK_V2_TEST(int a) {
fprintf (stdout, "version %d\n", a);
return;
} int main(int argc, char **argv) {
test(V1, 1);
test(V2, 2);
return 0;
}

4. 获取枚举变量的名字

枚举定义通常具有更好的可读性, 比如

enum enWeek_t {MONDAY, TUESDAY};

中MONDAY与TUSDAY比枚举值0,1有更好的可读性。事实上对于开发者,一个可读性更好的名称比这个名称的实际值加友好。如果是日志上能给出‘MONDAY’而不是 0这样的字眼,更能帮助我们理解。所以获取枚举类型的名称或许是个更好的选择。

一个示例:

enum_name.h

 #ifndef __ENUM_NAME_H__
#define __ENUM_NAME_H__ // MACRO_HELPER
#define MACRO_HELPER(v) v, #define WEEKDAYS \
MACRO_HELPER(MONDAY)
MACRO_HELPER(TUESDAY)
MACRO_HELPER(WEDNESDAY) // 这里宏替换会换成 enum {MONDAY, TUESDAY, WEDNESDAY,};
enum {
WEEKDAYS
};
16 #undef MACRO_HELPER(v)
#endif //__ENUM_NAME_H__

enum_name.c

 #include "enum_name.h"

 // 这里重新定义宏,利用编译器的特性 #v会把v原封不动的保存为一个字符串类型(## 两个#才是拼接,参考上一篇log函数的实现)
#define MACRO_HELPER(v) {v, #v},
struct week_name_t {
int val;
const char *name;
}; // 结构体的定义中成员顺序,必须和宏的定义一致 // 这里宏会替换成 struct week_names[] = {
// {MONDAY, "MONDAY"}, {TUESDAY, "TUESDAY"}, {WEDNESDAY, "WEDNESDAY"}, {0, 0}}
struct week_names[] = {
WEEKDAYS
{, } // this is the end of array
}; const char *get_enum_name(int v) {
int idx = ;
while (week_names[idx].name) {
if (idx == v)
return week_names[idx].name;
}
return "Unknow";
}

这里我们对外的唯一接口就是 get_enum_name 这个函数,只需要传入指定的数值,我们就能获得对应星期的名字。主要依赖宏替换的效果,如果想追加‘星期四’, ‘星期五’,我们只需要在头文件的 WEEKDAYS 添加 MACRO_HELPER(THURSDAY) 与 MACRO_HELPER(FRIDAY) 就行了,不要要其他的变动。接下来可以写个main函数测试下效果,我就不写了,只是抛砖引玉下。

当然你也可以编写一个函数把所有星期的名称字符串对应输出,这是你的自由,不在这个博问的讨论范围。

最新文章

  1. LoTVideo:只需两步,让HTML5原生态的Video茁壮成长
  2. Leetcode: Water and Jug Problem &amp;&amp; Summary: GCD求法(辗转相除法 or Euclidean algorithm)
  3. 我的android学习经历29
  4. 【剑指offer 面试题47】不用加减乘除做加法
  5. 进程间通信之XSI IPC
  6. ResourceManager架构解析
  7. jenkins全局安全设置
  8. [flask实践] 解决qq邮箱/mysql的相关配置问题
  9. python_如何让类支持比较运算?
  10. [Swift]LeetCode319. 灯泡开关 | Bulb Switcher
  11. 从0移植uboot (四) _点亮调试LED
  12. Java_集合面试题
  13. 解决idea控制台乱码及项目乱码
  14. Echarts饼图显示模板
  15. C++代码复习笔记:第三章
  16. Codeforces C - Om Nom and Candies
  17. 值得关注的sql-on-hadoop框架
  18. scala的一些特殊用法
  19. linux下man手册简介
  20. Jquery重新学习之九[Ajax运用总结C]

热门文章

  1. java中三大集合框架
  2. Es6扩展运算符--三点运算符(...)--展开语法(Spread syntax)
  3. 《Java从入门到失业》第一章:计算机基础知识(二):计算机组成及基本原理
  4. Vue3 + Element ui 后台管理系统
  5. pytest封神之路第一步 tep介绍
  6. 笔记:Windows Server2008R2服务安装
  7. CSS动画实例:太极图在旋转
  8. SparkSQL DSL 随便写写
  9. CSS动画实例:移动的眼珠子
  10. Java树形结构中根据父类节点查找全部子类节点