C语言中单井号(#)和双井号(##)在宏语句中的应用
来源:互联网 发布:安卓运行linux程序 编辑:程序博客网 时间:2024/05/21 09:40
作者:华清远见讲师
在阅读Linux内核代码过程中,特别是一些预处理指令宏的时候,会看到宏语句里会包含一些# 或者是连着的## 符号,刚接触的时候觉得很一头雾水,但这些宏语句有时候绕不开,所以为了更好地读懂这些代码,很有必要仔细学些一下这些特殊符号的含义。
# 的功能
# 的功能是将其后面的宏参数进行字符串化操作(stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。
1. #define WARN_IF(exp) \
2. do { \
3. if (exp) \
4. fprintf(stderr, "Warning: " #exp "\n"); \
5. } while(0)
现在在程序中以下面的方式调用这个宏:
1. WARN_IF (divider == 0);
那么在编译时,上面的这句话被扩展为:
1. do { if (divider == 0) fprintf(stderr, "Warning: " "divider == 0" "\n"); } while(0);
这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。
## 的功能
## 称为连接符号(concatenator),由两个# 号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元,注意这里连接的对象是token就行,而不一定是宏的变量。
下面举个例子来看看它们是怎样工作的。假设程序中已经定义了这样一个带参数的宏:
1. #define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d
现在在程序中以下面的方式调用这个宏:
1. struct _record_type LINK_MULTIPLE(name,company,position,salary);
那么在编译时,上面的这句话被扩展为:
1. struct _record_type name_company_position_salary;
综合举例
最后举一个综合# 和## 的例子。假设程序中已经定义了这样一个带参数的宏:
1. #define paster( n ) printf( "token" #n " = %d", token##n )
现在在程序中以下面的方式调用这个宏:
1. int token9 = 9;
2. paster( 9 );
那么在编译时,上面的paster( 9 ); 这句话被扩展为:
1. printf( "token" "9" " = %d", token9 );
注意到在这个例子中, paster(9); 中的这个9 被原封不动的当成了一个字符串,与”token”连接在了一起,从而成为了token9 。而#n 也被”9”所替代。 可想而知,上面程序运行的结果就是在屏幕上打印出
1. token9=9
相信大家理解了这些特殊符号在宏语句中的含义后,对阅读内核的代码会带来帮助。
原文:http://www.embedu.org/Column/3676.html
>>>更多优秀技术博文每日更新
- C语言中单井号(#)和双井号(##)在宏语句中的应用
- C语言应用系列: 01. 宏在项目中的应用
- c语言应用系列: 01. 宏在项目中的应用
- C语言可变参数在宏定义中的应用
- C语言可变参数在宏定义中的应用
- 数据结构在C语言中的应用
- static在C语言中的应用
- CONST在C语言中的应用
- extern 在C语言中的应用
- enum自学--在C语言中的应用
- Static在C语言中的应用
- C语言-数据类型在LR中的应用
- static关键字在c语言中的应用
- C语言中的位运算在嵌入式中的应用
- C语言"#","#@"和"##"在宏定义中的使用技巧
- 关于#和##在C语言的宏中的使用
- C语言中的for语句
- C语言中的break语句
- TaintDroid深入剖析之启动篇
- spring 定时任务注入sessionfactory
- 怎么去检测浏览器支不支持html5和css3?
- 深入理解分布式事务
- APP主题设置大全
- C语言中单井号(#)和双井号(##)在宏语句中的应用
- 对象输入流和输出流
- Linux下安装Zookeeper
- 07.04C
- 【2019】数的质因子
- Properties(配置文件类)
- Elasticsearch java API (22)查询 DSL Joining查询
- -隐式类型转换
- 编写程序tail,将其输入中的最后n行打印出来。