C 语言几个绝招
符号展开连接
1 2 3 |
#define CAT_TOKEN_1(t1, t2)? t1##t2 #define CAT_TOKEN_2(t1, t2)? CAT_TOKEN_1(t1,t2) #define CAT_TOKEN CAT_TOKEN_2 |
CAT_TOKEN_1 将 t1 和 t2 连接成 t1t2 ,不预先将 t1 和 t2 展开,而
CAT_TOKEN_2 将 t1 和 t2 展开后再连接,如:
1 2 3 4 5 |
#define t1 I_am_ #define t2 lei_peng CAT_TOKEN_1(t1, t2) // 结果是 t1t2 CAT_TOKEN_2(t1, t2) // 结果是 I_am_leipeng |
将0转化为0,而将非零转化为 1,可以转化指针
1 |
#define convert_bool(x) (!!(x)) |
编译时断言
1 2 3 4 5 |
#define COMPILE_ASSERT(x)? \ enum { CAT_TOKEN (comp_assert_, __LINE__) = 1 / !!(x) }; // 或者 #define COMPILE_ASSERT_2(x)?\ void CAT_TOKEN(comp_assert_fun_,__LINE__)? (int x[][x]); |
定义 Handle类型
1 2 3 |
#define? DEFINE_HANDLE_TYPE(handle_type)? \ struct param_##handle_type; \ typedef? void? (*handle_type )(struct param_##handle_type); |
将 Handle 定义为函数指针主要有一个好处:就是禁止了对 Handle 的加减,防止了一些小错误的发生。
定义union中的匿名 struct
1 2 3 4 5 6 7 |
struct my_type { union { struct { … } u1; struct { … } u2; struct { … } u3; }; }; |