当前位置: 首页 > news >正文

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. likelyunlikely

这些宏用于提示编译器某些条件更可能(或不太可能)成立,从而优化分支预测。

#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_entrylist_for_each

在实现内核链表时,list_entrylist_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. MINMAX

用于计算两个数中的最小值和最大值。

#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. BITSET_BITCLEAR_BITTOGGLE_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_UPROUND_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
在这里插入图片描述


http://www.mrgr.cn/news/67318.html

相关文章:

  • C++builder中的人工智能(7)如何在C++中开发特别的AI激活函数?
  • 【React】JSX规则
  • C#-类:静态成员的介绍
  • c语言安全分析(一)——字符串(1)
  • 求平面连接线段组成的所有最小闭合区间
  • 【UE5】可以实时绘制的体积渲染 【第三章 体积纹理绘制 - 3.绘制体积】
  • 【LeetCode】【算法】238. 除自身以外数组的乘积
  • Star Tower:开启数据存储新纪元
  • 运动控制 PID算法
  • 掌握 PyQt5:从零开始的桌面应用开发
  • Kubernetes 服务发现:Service、DNS 深度解析
  • 迷你版VFB,极简的Freebasic开发IDE-VB7-vb6编程开发
  • Java——异常
  • 【709】基于SSM+vue的“萌宠小知识”网站设计与实现
  • 3254. 长度为 K 的子数组的能量值 I
  • STM32F103 单片机
  • 初识Mysql数据库
  • Appium环境搭建/使用教程(图文超详细)
  • 高并发内存池扩展 -- 处理大内存,优化释放时需要传入空间大小,加入定长内存池,存放映射关系的容器的锁机制,优化性能(基数树,优势,优化前后对比)
  • Cesium中granularity关键字引起的连锁知识
  • 【系统架构设计师】高分论文:论企业集成平合的技术与应用
  • C语言-详细讲解-洛谷P1075 [NOIP2012 普及组] 质因数分解
  • Cookie技术详解:互联网中的“记忆”使者
  • Jenkins应用详解(Detailed Explanation of Jenkins Application)
  • 使用Golang实现开发中常用的【实例设计模式】
  • 秒杀系统设计:原则、关键技术与注意事项