C 语言 宏定义 :字符串化 stringify 的应用
字符串化
通过C 语言的宏(MICRO),可以把数值或者一段字符的组合,转换为字符串。
因为 C语言的宏在【预处理】阶段就展开了,所以可以实现一些比较使用的功能,比如一些数据的初始化操作
比如定义一个宏,传入的宏的参数是一个 func 函数名,经过宏的层层处理,可以把这个函数名以字符串的方式取出来,并赋值给结构体的 字符指针成员
示例:
struct rt_init_desc{const char* fn_name;const init_fn_t fn;};#define INIT_EXPORT(fn, level) \const char __rti_##fn##_name[] = #fn; \RT_USED const struct rt_init_desc __rt_init_desc_##fn SECTION(".rti_fn." level) = \{ __rti_##fn##_name, fn};
这里的 INIT_EXPORT 的 作用是 在 段中初始化一个数据结构:代码可以通过变量多个这样的数据结构,获取可执行函数的指针,从而实现 【自动初始化】机制。
这个操作有两个特点:(1)代码得到简化 (2)
fn
函数名【字符串化】然后组合成一个新的字符串,对数据成员const char *fn_name
进行初始化
字符串化
宏定义中,通过一个
#
就可以把 一串字符,转换为字符串,这里的一串字符,可以是一个数值,可以是一个函数指针(函数名)如:
#fn
,就把fn
这个参数,转换为 C 语言中的字符串(常量)了字符串化最经典的 转换宏:
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
__stringify_1(5)
获取的 是"5"
,也就是5
转换为 字符串"5"
了__stringify
的作用更强大,如果传入的参数也是个【宏定义】,会继续展开,并转换
#define STRING_NAME "5"
#define DEV_DEMO_NAME1 __stringify(STRING_NAME)
这时
DEV_DEMO_NAME1
不再是 字符串 “STRING_NAME”,而是 “5”
字符串连接
宏定义中,通过两个
##
可以把两个字符串连接起来,也就是【拼接】起来__rti_##fn##_name
, 如果 fn 为hello
,则 展开后为__rti_hello_name
,这里的##
起到了字符串(拼接)连接的作用,展开后##
就不存在了
测试一下
#include <stdio.h>#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)#define STRING_NAME "5"
#define DEV_DEMO_NAME __stringify(5)
#define DEV_DEMO_NAME1 __stringify(STRING_NAME)
#define DEV_DEMO_NAME2 __stringify(DEVICE_NAME_HELLO)int main()
{printf("%s enter\n", __func__);printf("%s : DEVICE_NAME : %s \n", __func__, STRING_NAME);printf("%s : DEV_DEMO_NAME : %s \n", __func__, DEV_DEMO_NAME);printf("%s : DEV_DEMO_NAME1 : %s \n", __func__, DEV_DEMO_NAME1);printf("%s : DEV_DEMO_NAME2 : %s \n", __func__, DEV_DEMO_NAME2);return 0;
}
测试环境为:ubuntu 20.04 Linux 环境
编译:
$ gcc micro_string_test.c -o micro_string_test
运行效果:
zhangsz@zhangsz-virtual-machine:~/linux/codes/202302/0212$ ./micro_string_test
main enter
main : DEVICE_NAME : 5
main : DEV_DEMO_NAME : 5
main : DEV_DEMO_NAME1 : "5"
main : DEV_DEMO_NAME2 : DEVICE_NAME_HELLO
- 简单的解释:
#define STRING_NAME "5"
直接定义一个字符串"5"
,而不是数值5
__stringify(5)
的作用把5
转换为 字符串了,这就是普通的 【字符串化】#define DEV_DEMO_NAME2 __stringify(DEVICE_NAME_HELLO)
,由于DEVICE_NAME_HELLO
不是一个可以展开的【宏】,所以依旧转换为普通的字符串DEVICE_NAME_HELLO
#define DEV_DEMO_NAME1 __stringify(STRING_NAME)
,由于STRING_NAME
是个宏,内容是"5"
,所以再次展开为"5"
,而不是STRING_NAME
,注意这个"5"
是有双引号的,因为【宏】是【替换】
小结
在操作系统中,C语言的宏非常的多,有些宏定义,使用起来跟函数相差不多,有些宏的使用,大大简化了代码量,让代码看起来非常的整洁美观
当然过多的【宏】,依旧需要不断的查看展开的效果,过长的的【宏定义】,加大了代码阅读的难度,让代码晦涩难懂
宏定义的函数,不利于软件【单步调试】
C 语言 宏定义 :字符串化 stringify 的应用相关推荐
- C语言把宏定义字符串化
原文链接 有时候想要把一个宏定义的内容嵌入到字符串中去. 例如宏定义: #define RATE 15000 #define STR1(R) #R #define STR2(R) STR1(R)pri ...
- c语言宏定义字符串 换行_C语言换行
(一) 这几天正在看 ATMEL 的 ARM 处理器 AT91SAM7X256 ,在其官方的头文件中发现有如下宏定义: #define SPI0_PINS (AT91C_PA17_SPI0_MOSI ...
- C语言-宏定义和字符串
C语言-宏定义和字符串 定义符号常量(宏定义) 格式 下面我们看看如何在C语言中写宏定义呢 接下来我们看看运行结果吧 关于c语言中的字符串 定义符号常量(宏定义) 把程序中出现的所有标识符,替换为已经 ...
- c语言宏定义的连接符##和#转字符串
c语言宏定义的连接符有哪些 [此问题的推荐答案] (一)宏定义中的## 连接符与# 符 ## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串. ...
- C/C++语言宏定义##连接符和符#的使用
C/C++语言宏定义##连接符和符#的使用 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/53113187 (一) ...
- c语言 宏do while,关于C语言宏定义 使用do{ xxxx }while()
暂时感觉像是由于":"的原因,关于使用习惯方面的问题!! 下面是copy的: 这样的宏见过么: Cpp代码 #define FOO(x) do {\ some_code_line_ ...
- C语言宏定义-跟踪调试宏
C语言宏定义-跟踪调试宏 文章目录 C语言宏定义-跟踪调试宏 1. 简介 2. 相关宏 3. 例子 1. 简介 标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预 ...
- C语言宏定义中#号的作用
C语言宏定义中#号的作用 前言 #号的作用 前言 最近,在阅读uboot的源码过程中,发现了一段宏定义代码: #define U_BOOT_CMD_MKENT_COMPLETE(_name, _max ...
- c语言中#39;xd#39;代表什么,关于C语言宏定义的技巧:#39;##39;和#39;###39;
关于C语言宏定义的技巧:'#'和'##' '#'和'##' '#'和'##'是两个预处理运算符,只能在预处理的过程中使用.在带参数的宏定义中, '#'运算符后面应该跟一个参数,预处理器会把这个参数转换 ...
- c语言宏定义技巧和用法,关于C语言宏定义的技巧:'#'和'##'
关于C语言宏定义的技巧:'#'和'##' '#'和'##' '#'和'##'是两个预处理运算符,只能在预处理的过程中使用.在带参数的宏定义中, '#'运算符后面应该跟一个参数,预处理器会把这个参数转换 ...
最新文章
- java float内存结构_Java后端开发岗必备技能:Java并发中的内存模型
- autoconfig oracle,ORACLE EBS 执行autoconfig time out
- python中用lxml解析html
- python项目实战:最简单的图片转字符画
- 超图桌面版加载obj 3D模型
- VS2015安装简单的C#单元测试
- 架构师养成之道-01-知识图谱
- linux spyder 目录,linux下创建spyder桌面图标的方法
- django新建php文件,在Python的Django框架中创建语言文件
- const没define好用 php,3分钟短文|PHP 定义常量,我该用define还是const?这下不迷茫了...
- Bitmap尺度变换
- C# WinForm程序退出的方法
- 保存文件_正确保存Zbrush文件
- 质性数据分析软件NVivo教程:自动编码情感
- 电信 dns服务器 不稳定,网速不稳定的解决方法:修改本地DNS
- [每日一氵] mmSeg 报错 StopIteration
- 算法 图8 How Long Does It Take
- OL3-Cesium 二三维鼠标事件统一处理
- java security_java.security.NoSuchAlgorithmException
- 环境变量LC相关设置