网站建设的总结seo常用工具
字符串化
-
通过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语言的宏非常的多,有些宏定义,使用起来跟函数相差不多,有些宏的使用,大大简化了代码量,让代码看起来非常的整洁美观
-
当然过多的【宏】,依旧需要不断的查看展开的效果,过长的的【宏定义】,加大了代码阅读的难度,让代码晦涩难懂
-
宏定义的函数,不利于软件【单步调试】