C语言常用的宏定义
引言
- 在C语言编程中,宏定义不仅可以使代码更简洁,而且在某些场景下能够显著提高代码的性能和可维护性。本文将介绍一些常见的高级宏定义及其使用方法。
目录
- 引言
- 1. `offsetof`
- 2. `typeof`
- 3. `likely` 和 `unlikely`
- 4. `container_of`
- 5. `list_entry` 和 `list_for_each`
- 6. `stringify`
- 7. `ARRAY_SIZE`
- 8. `container_of_safe`
- 9. `MIN` 和 `MAX`
- 10. `ABS`
- 11. `NULL`
- 12. `BIT` 和 `SET_BIT`、`CLEAR_BIT`、`TOGGLE_BIT`
- 13. `IS_POWER_OF_TWO`
- 14. `ROUND_UP` 和 `ROUND_DOWN`
- 15. `ALIGN`
- 16. `SWAP`
- 17. `CONCAT`
- 18. `CHECK_FLAG`
1. offsetof
offsetof
宏用于计算结构体成员相对于结构体起始位置的偏移量,常用于与 container_of
一起使用。
#include <stddef.h>struct my_struct {int a;float b;char c;
};size_t offset = offsetof(struct my_struct, c);
2. typeof
typeof
宏用于获取变量的类型,可以在编写宏定义时确保类型一致性。
#define SWAP(a, b) do { \typeof(a) _tmp = (a); \(a) = (b); \(b) = _tmp; \
} while (0)int x = 5, y = 10;
SWAP(x, y); // x 现在是 10, y 是 5
3. likely
和 unlikely
这些宏用于提示编译器某些条件更可能(或不太可能)成立,从而优化分支预测。
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)if (likely(x > 0)) {// 很可能执行的代码路径
} else {// 不太可能执行的代码路径
}
4. container_of
container_of
宏用于从成员指针获取结构体指针。
#define container_of(ptr, type, member) \(type *)((char *)(ptr) - offsetof(type, member))
5. list_entry
和 list_for_each
在实现内核链表时,list_entry
和 list_for_each
是非常有用的宏,简化了链表操作。
#define list_entry(ptr, type, member) \container_of(ptr, type, member)#define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)
6. stringify
stringify
宏用于将宏参数转换为字符串。
#define stringify(x) #x#define DEBUG_VAR(var) printf("The value of " #var " is %d\n", var)int var = 10;
DEBUG_VAR(var); // 输出:The value of var is 10
7. ARRAY_SIZE
用于计算数组的元素个数,非常适合在编写数组相关的宏或函数时使用。
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))int array[10];
size_t size = ARRAY_SIZE(array); // size 是 10
8. container_of_safe
这是一个更安全的 container_of
版本,避免空指针问题。
#define container_of_safe(ptr, type, member) \({ \typeof(ptr) _ptr = (ptr); \_ptr ? (type *)((char *)(_ptr) - offsetof(type, member)) : NULL; \})
9. MIN
和 MAX
用于计算两个数中的最小值和最大值。
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
10. ABS
用于计算一个数的绝对值。
#define ABS(x) ((x) < 0 ? -(x) : (x))
11. NULL
表示空指针。
#define NULL ((void*)0)
12. BIT
和 SET_BIT
、CLEAR_BIT
、TOGGLE_BIT
用于位操作的宏定义。
#define BIT(x) (1 << (x))
#define SET_BIT(value, bit) ((value) |= BIT(bit))
#define CLEAR_BIT(value, bit) ((value) &= ~BIT(bit))
#define TOGGLE_BIT(value, bit) ((value) ^= BIT(bit))
13. IS_POWER_OF_TWO
用于判断一个数是否是2的幂。
#define IS_POWER_OF_TWO(x) ((x) != 0 && ((x) & ((x) - 1)) == 0)
14. ROUND_UP
和 ROUND_DOWN
用于向上和向下舍入到最接近的整数倍。
#define ROUND_UP(x, multiple) (((x) + (multiple) - 1) / (multiple) * (multiple))
#define ROUND_DOWN(x, multiple) ((x) / (multiple) * (multiple))
15. ALIGN
用于将地址或大小对齐到指定的边界。
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
16. SWAP
交换两个变量的值。
#define SWAP(a, b) do { \typeof(a) _tmp = (a); \(a) = (b); \(b) = _tmp; \
} while (0)
17. CONCAT
用于宏参数的连接
#define CONCAT(a, b) a##b
18. CHECK_FLAG
检查某个标志位是否被设置。
#define CHECK_FLAG(value, flag) (((value) & (flag)) != 0)
end