赏心悦目的宏代码

来源:互联网 发布:oracle查询当天数据 编辑:程序博客网 时间:2024/05/22 15:16

from:http://blog.csdn.net/shallwake/article/details/5267726

常常看到一些优秀的宏代码,惊叹之余也就不了了之,今天在这做一个整理,也许不够完善,以后会继续补充。

 

补充一个用于模块化开发:刚写完去逛云风GG Blog就发现了。。http://blog.codingnow.com/2010/01/c_modularization.html#mor

索引:

1.1  避免重复包含头文件

1.2  ACM刷题用的宏

1.3  用于开发跨平台代码

1.4  Dll导入导出函数确定

2.1  一些常用的简单的宏

2.2  windows assert()宏(转自hplonline )

2.3  用宏实现STL中的foreach函数

2.4  do{}while(0)应用

2.5  取结构中成员的偏移量

2.6  宏遍历

2.7  最后贴一个kasicass GG的开源代码,纯粹宏实现的double linked list

一,用于条件编译:

1,避免重复包含头文件:

#ifndef SOME_H
#define SOME_H
……………………

…………………
#endif

2,ACM刷题用的宏,

#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin) ;
#endif

主要是输入流重定向,方便本地测试。

3,用于开发跨平台代码

#if defined(UNIX)
    //here is unix code
#else
    //here is windows code
#endif

4,Dll导入导出函数确定

#ifdef DLL_FILE
class _declspec(dllexport) point //导出类point
#else
class _declspec(dllimport) point //导入类point
#endif

以上是Dll头文件dll.h,下面是实现文件需要的宏

#ifndef DLL_FILE
#define DLL_FILE
#endif
#include "dll.h"

总结:灵活运用可以写出非常强大的代码,一般大型开源程序的跨平台核心都包含了各种条件编译。

 

二,用于简化代码,提高效率

1,一些常用的简单的宏:

#define ABS(x) ((x) < 0 ? -(x) : (x))
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )

还有很多,就不列举了。。

2,windows assert()宏(转自 hplonline

_CRTIMP void __cdecl _assert(void *, void *, unsigned);
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )

别小看这样一个宏,彻底搞懂收获挺大的,详细可以看http://hi.baidu.com/hplonline/blog/item/8637ab4470ee268bb3b7dcaa.html

3,用宏实现STL中的foreach函数

#define FOREACH(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)

typedefvector VS;
vector  publications

FOREACH(it,publications) {
VS V = operate(*it);
}

厌烦了STL中琐碎的iterator遍历了吗,试试这个宏,巧妙之处在于__typeof((c).begin()) it=(c).begin(),呵呵

4,do{}while(0)应用。

比如一个清楚指针的宏:#define XFREE(ptr) do { if (ptr) free(ptr); } while(0)

注意为什么要把if()放入do{}while(0)呢。。。不是多此一举吗?感谢赵老师指点,考虑下面的情况:

if (a)
XFREE(ptr);
else
xxxxx;

若没有do{}while(0),展开后,else与if不配对了。。

5,取结构中成员的偏移量

#define   offsetof(TYPE,   MEMBER)   ((size_t)   &((TYPE   *)0)->MEMBER)
TYPE为结构类型名 MEMBER为成员名可以这样理解;TYPE *ptype;ptype = (TYPE *) 0; /* 强制把0值转换成TYPE类型的指针赋给ptype*/&(ptype->MEMBER) /* 返回成员MEMBER成员的地址 */因为ptype指针的是0;则成员MEMBER的地址就是 0+偏移量size_t 强制把结果转换成size_t类型

这个宏在Linux内核中使用很多,感兴趣的可以参考Linux的list.h实现

6,宏遍历

列举一个windows下select模型的FD_SET宏吧,有了上面的基础,理解起来应该不难。

#define FD_SET(fd, set) do { /
    u_int __i; /
    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { /
        if (((fd_set FAR *)(set))->fd_array[__i] == (fd)) { /
            break; /
        } /
    } /
    if (__i == ((fd_set FAR *)(set))->fd_count) { /
        if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { /
            ((fd_set FAR *)(set))->fd_array[__i] = (fd); /
            ((fd_set FAR *)(set))->fd_count++; /
        } /
    } /
} while(0)

7,最后贴一个kasicass GG的开源代码,纯粹宏实现的double linked list,呵呵~项目地址:http://github.com/kasicass/kircdlist.h代码如下,大家可以直接拿来用的哦

#ifndef KCODE_COMMON_LIST_H
#define KCODE_COMMON_LIST_H
// ------------- double-linked list ---------------
/*
* List declarations.
*/
#define K_LIST_HEAD(name, type) /
struct name { /
struct type *lh_first; /* first element */ /
}
#define K_LIST_HEAD_INITIALIZER(head) /
{ NULL }
#define K_LIST_ENTRY(type) /
struct { /
struct type *le_next; /* next element */ /
struct type **le_prev; /* address of previous next element */ /
}
/*
* List functions.
*/
#define K_LIST_EMPTY(head) ((head)->lh_first == NULL)
#define K_LIST_FIRST(head) ((head)->lh_first)
#define K_LIST_FOREACH(var, head, field) /
for ((var) = K_LIST_FIRST((head)); /
(var); /
(var) = K_LIST_NEXT((var), field))
#define K_LIST_FOREACH_SAFE(var, head, field, tvar) /
for ((var) = K_LIST_FIRST((head)); /
(var) && ((tvar) = K_LIST_NEXT((var), field), 1); /
(var) = (tvar))
#define K_LIST_INIT(head) do { /
K_LIST_FIRST((head)) = NULL; /
} while (0)
#define K_LIST_INSERT_AFTER(listelm, elm, field) do { /
if ((K_LIST_NEXT((elm), field) = K_LIST_NEXT((listelm), field)) != NULL) /
K_LIST_NEXT((listelm), field)->field.le_prev = /
&K_LIST_NEXT((elm), field); /
K_LIST_NEXT((listelm), field) = (elm); /
(elm)->field.le_prev = &K_LIST_NEXT((listelm), field); /
} while (0)
#define K_LIST_INSERT_BEFORE(listelm, elm, field) do { /
(elm)->field.le_prev = (listelm)->field.le_prev; /
K_LIST_NEXT((elm), field) = (listelm); /
*(listelm)->field.le_prev = (elm); /
(listelm)->field.le_prev = &K_LIST_NEXT((elm), field); /
} while (0)
#define K_LIST_INSERT_HEAD(head, elm, field) do { /
if ((K_LIST_NEXT((elm), field) = K_LIST_FIRST((head))) != NULL) /
K_LIST_FIRST((head))->field.le_prev = &K_LIST_NEXT((elm), field); /
K_LIST_FIRST((head)) = (elm); /
(elm)->field.le_prev = &K_LIST_FIRST((head)); /
} while (0)
#define K_LIST_NEXT(elm, field) ((elm)->field.le_next)
#define K_LIST_REMOVE(elm, field) do { /
if (K_LIST_NEXT((elm), field) != NULL) /
K_LIST_NEXT((elm), field)->field.le_prev = /
(elm)->field.le_prev; /
*(elm)->field.le_prev = K_LIST_NEXT((elm), field); /
} while (0)
#endif

原创粉丝点击