注:
1、以下用法需要C99的支持,均在windows xp 32bit系统上测试;其他平台或C语言标准未测试。
2、版权所有,转载请注明出处,欢迎转载。
一、解释
1、#:作用是将参数转为字符串,仅允许出现在带参数的宏的替换列表中。#n变成 "n" ,注意双引号不能省略
例如:
#define PRINT(n) printf(#n "= %d\n",n)
PRINT(i/j);
替换后为:printf("i/j" "= %d\n",i/j);相邻两个""会被抵消,所以就等价于
printf("i/j = %d\n",i/j);
2、##:符号连接作用,即把##前后的符号连接(粘合)在一起。
例如:
#define PINX(n) x##n
PINX(1);
展开后就是:x1
3、__VA_ARGS__ 和... :可变参数的宏,意思就是后面可以跟许多参数
例如:
以下代码来自:https://www.amobbs.com/thread-5542774-1-1.html
#ifndef __OOPC_H__
#define __OOPC_H__
#include <stdint.h>
#define EXTERN_CLASS(__NAME,...) \
typedef union __NAME __NAME;\
__VA_ARGS__\
union __NAME {\
uint_fast8_t chMask[(sizeof(struct {
#define END_EXTERN_CLASS(__NAME) \
}) + sizeof(uint_fast8_t) - 1) / sizeof(uint_fast8_t)];\
};
#define DEF_CLASS(__NAME,...)\
typedef union __NAME __NAME;\
__VA_ARGS__\
typedef struct __##__NAME __##__NAME;\
struct __##__NAME{
#define END_DEF_CLASS(__NAME) \
};\
union __NAME {\
uint_fast8_t chMask[(sizeof(__##__NAME) + sizeof(uint_fast8_t) - 1) / sizeof(uint_fast8_t)];\
};
#define CLASS(__NAME) __##__NAME
#endif /* __OOPC_H__ */
再定义2个对象
EXTERN_CLASS(key_queue_t)
key_event_t *ptBuffer;
uint16_t hwSize;
uint16_t hwHead;
uint16_t hwTail;
uint16_t hwLength;
END_EXTERN_CLASS(key_queue_t)
DEF_CLASS(key_queue_t)
key_event_t *ptBuffer;
uint16_t hwSize;
uint16_t hwHead;
uint16_t hwTail;
uint16_t hwLength;
END_DEF_CLASS(key_queue_t)
展开后的结果为:
typedef union key_queue_t key_queue_t;\
__VA_ARGS__\
union key_queue_t {\
uint_fast8_t chMask[(sizeof(struct {
key_event_t *ptBuffer;
uint16_t hwSize;
uint16_t hwHead;
uint16_t hwTail;
uint16_t hwLength;
}) + sizeof(uint_fast8_t) - 1) / sizeof(uint_fast8_t)];\
};
删除多余的部分后就为
typedef union key_queue_t key_queue_t;
union key_queue_t
{
uint_fast8_t chMask[(sizeof(struct {
key_event_t *ptBuffer;
uint16_t hwSize;
uint16_t hwHead;
uint16_t hwTail;
uint16_t hwLength;
}) + sizeof(uint_fast8_t) - 1) / sizeof(uint_fast8_t)];
};
typedef union key_queue_t key_queue_t;\
__VA_ARGS__\
typedef struct __##key_queue_t __##key_queue_t;\
struct __##key_queue_t{
key_event_t *ptBuffer;
uint16_t hwSize;
uint16_t hwHead;
uint16_t hwTail;
uint16_t hwLength;
};\
union key_queue_t {\
uint_fast8_t chMask[(sizeof(__##key_queue_t) + sizeof(uint_fast8_t) - 1) / sizeof(uint_fast8_t)];\
};
去掉##后的语句为:
typedef union key_queue_t key_queue_t;\
__VA_ARGS__\
typedef struct __key_queue_t __key_queue_t;\
struct __key_queue_t{
key_event_t *ptBuffer;
uint16_t hwSize;
uint16_t hwHead;
uint16_t hwTail;
uint16_t hwLength;
};\
union key_queue_t {\
uint_fast8_t chMask[(sizeof(__key_queue_t) + sizeof(uint_fast8_t) - 1) / sizeof(uint_fast8_t)];\
};
去掉其他多余语句后的结果为:
typedef union key_queue_t key_queue_t;
typedef struct __key_queue_t __key_queue_t;
struct __key_queue_t
{
key_event_t *ptBuffer;
uint16_t hwSize;
uint16_t hwHead;
uint16_t hwTail;
uint16_t hwLength;
};
union key_queue_t {
uint_fast8_t chMask[(sizeof(__key_queue_t) + sizeof(uint_fast8_t) - 1) / sizeof(uint_fast8_t)];
};
2020-03-04@北京 晴