首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C语言带参数的宏定义的相关知识汇总(最常用的形式、带标记分隔符##的形式...)

  • 25-03-05 05:21
  • 4268
  • 9757
blog.csdn.net

阅读大型C工程代码时,绕不开带参数的宏定义的阅读,所以有必要强化一下这一块的知识。

01-带参数的宏定义最常用的形式

# define S(a,b) a*b
...
...
...
area = S(3,2);
  • 1
  • 2
  • 3
  • 4
  • 5

则在编译预处理时area = S(3,2);被展开为:

area = 3 * 2;
  • 1

02-带标记分隔符##的宏定义

为什么要引入标记分隔符##?

在 C 语言的 预处理器中,对于带参数的宏替换,实际上是以标记为单位来替换的。
比如在下面的宏定义:

# define S(a,b) a*b
  • 1

在a*b中,a是一个标记,b也是一个标记,两个标记通过运算符*进行了划分。
在实际展开时,第一个参数名因为与第一个标记相同,所以去替换第一个标记a;第二个参数名因为与第二个标记相同,所以去替换第二个标记b。

又如:

# define S(aaa,bbb) aaa*bbb
  • 1

在aaa*bbb中,aaa是一个标记,bbb也是一个标记,两个标记通过运算符*进行了划分。
在实际展开时,第一个参数名因为与第一个标记相同,所以去替换第一个标记aaa;第二个参数名因为与第二个标记相同,所以去替换第二个标记bbb。
此时

S(su,wenhao)
  • 1

会展开为:su*wenhao

但是对于下面这个宏定义:

#define S1(aaa, bbb) aaa*bbbk
  • 1

就出问题了,因为在aaa*bbbk中,两个标记分别为aaa和bbbk(两个标记通过运算符*进行了划分),第一个参数名因为与第一个标记相同,所以去替换第一个标记aaa,第二个参数名因与第二个标记bbbk不相同,所以无法替换,此时:

S(su,wenhao)
  • 1

的展开结果为:su*bbbk。
但其实我们这里想得到的结开结果为su*wenhaok

那么办呢?我们就需要在bbb和k之间加一个标记分隔符,这个标记分隔符就是##,即把宏定义写成下面这样就能得到我们想要的结果:

#define S1(aaa, bbb) aaa*bbb##k
  • 1

## 的用途举例

1. 动态生成变量名

通过宏创建多个变量名:

#define CREATE_VAR(name) int var_##name;
CREATE_VAR(foo)  // 生成 int var_foo;
CREATE_VAR(bar)  // 生成 int var_bar;
  • 1
  • 2
  • 3
2. 动态生成函数

可以用宏来定义多个函数:

#define CREATE_FUNC(name) void func_##name(void) { printf(#name " function called\n"); }
CREATE_FUNC(init)  // 生成 void func_init(void) { printf("init function called\n"); }
CREATE_FUNC(exit)  // 生成 void func_exit(void) { printf("exit function called\n"); }
  • 1
  • 2
  • 3

调用时:

func_init();  // 输出:init function called
func_exit();  // 输出:exit function called
  • 1
  • 2

我在实际工程中遇到使用##的例子

在Linux嵌入式驱动开发中,对于设备类的属性的定义用到了带##的宏。

CLASS_ATTR_WO(led_all_control);
  • 1

这个宏的定义如下:

#define CLASS_ATTR_WO(_name) struct class_attribute class_attr_##_name = __ATTR_WO(_name)
  • 1

由于分隔符##的存在,所以_name成为一个标记,所以CLASS_ATTR_WO(led_all_control);会被展开为:

struct class_attribute class_attr_led_all_control = __ATTR_WO(led_all_control)
  • 1

上面这个展开式的右边其实又是一个带参数的宏定义,这里我就不把它展开了,我们这里重点是强调宏标记分隔符##的使用。

昊虹嵌入式技术交流群
QQ群名片
注:本文转载自blog.csdn.net的昊虹AI笔记的文章"https://blog.csdn.net/wenhao_ir/article/details/144908107"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top