gnu 扩展之#和##
转自:http://chongsoft.bokee.com/5816474.html
今天测试了宏定义中的 "#" 和 "##" 的区别。
结果如下:
"#" 代表和一个字符串相连接
"##" 代表和一个符号连接,符号可以是变量,或另一个宏符号。
举例如下:
宏定义如下
(1)
#define DEV_FILE_NAME "/dev/test_kft"
#define OPEN_FILE(fd, n) \
{ \
fd = open(DEV_FILE_NAME #n,O_RDONLY); \
if(fd < 0) \
{ \
printf("Open device error\n"); \
return 0; \
} \
}
如此调用:
OPEN_FILE(fd1, 1);
OPEN_FILE(fd2, 2);
OPEN_FILE(fd3, 3);
OPEN_FILE(fd4, 4);
OPEN_FILE(fd5, 5);
OPEN_FILE(fd6, 6);
用gcc -E展开后,如下
2299: { fd1 = open("/dev/test_kft" "1",00); if(fd1 < 0) { printf("Open device error\n"); return 0; } };
2300: { fd2 = open("/dev/test_kft" "2",00); if(fd2 < 0) { printf("Open device error\n"); return 0; } };
2301: { fd3 = open("/dev/test_kft" "3",00); if(fd3 < 0) { printf("Open device error\n"); return 0; } };
2302: { fd4 = open("/dev/test_kft" "4",00); if(fd4 < 0) { printf("Open device error\n"); return 0; } };
2303: { fd5 = open("/dev/test_kft" "5",00); if(fd5 < 0) { printf("Open device error\n"); return 0; } };
2304: { fd6 = open("/dev/test_kft" "6",00); if(fd6 < 0) { printf("Open device error\n"); return 0; } };
如果没有定义DEV_FILE_NAME ,就是
2299: { fd1 = open(DEV_FILE_NAME "1",00); if(fd1 < 0) { printf("Open device error\n"); return 0; } };
2300: { fd2 = open(DEV_FILE_NAME "2",00); if(fd2 < 0) { printf("Open device error\n"); return 0; } };
2301: { fd3 = open(DEV_FILE_NAME "3",00); if(fd3 < 0) { printf("Open device error\n"); return 0; } };
2302: { fd4 = open(DEV_FILE_NAME "4",00); if(fd4 < 0) { printf("Open device error\n"); return 0; } };
2303: { fd5 = open(DEV_FILE_NAME "5",00); if(fd5 < 0) { printf("Open device error\n"); return 0; } };
2304: { fd6 = open(DEV_FILE_NAME "6",00); if(fd6 < 0) { printf("Open device error\n"); return 0; } };
所以可以很清楚的看出#n 解析出来的是"n" , 用于连接一个已有的字符串。
(2) 再来看 ## 是什么意思, 宏定义如下:
#define OPEN_FILE(fd, n) \
{ \
fd = open(DEV_FILE_NAME ##n,O_RDONLY); \
if(fd < 0) \
{ \
printf("Open device error\n"); \
return 0; \
} \
}
调用方式相同。
看宏展开:
2299: { fd1 = open(DEV_FILE_NAME1,00); if(fd1 < 0) { printf("Open device error\n"); return 0; } };
2300: { fd2 = open(DEV_FILE_NAME2,00); if(fd2 < 0) { printf("Open device error\n"); return 0; } };
2301: { fd3 = open(DEV_FILE_NAME3,00); if(fd3 < 0) { printf("Open device error\n"); return 0; } };
2302: { fd4 = open(DEV_FILE_NAME4,00); if(fd4 < 0) { printf("Open device error\n"); return 0; } };
2303: { fd5 = open(DEV_FILE_NAME5,00); if(fd5 < 0) { printf("Open device error\n"); return 0; } };
2304: { fd6 = open(DEV_FILE_NAME6,00); if(fd6 < 0) { printf("Open device error\n"); return 0; } };
现在看清楚了, ##n 的作用是把n直接连接在了一个符号的末尾. 好, 现在我们定义一个符号看看效果。
#define DEV_FILE_NAME1 "/dev/test_kft1"
再展开:
2299: { fd1 = open("/dev/test_kft1",00); if(fd1 < 0) { printf("Open device error\n"); return 0; } };
2300: { fd2 = open(DEV_FILE_NAME2,00); if(fd2 < 0) { printf("Open device error\n"); return 0; } };
2301: { fd3 = open(DEV_FILE_NAME3,00); if(fd3 < 0) { printf("Open device error\n"); return 0; } };
2302: { fd4 = open(DEV_FILE_NAME4,00); if(fd4 < 0) { printf("Open device error\n"); return 0; } };
2303: { fd5 = open(DEV_FILE_NAME5,00); if(fd5 < 0) { printf("Open device error\n"); return 0; } };
2304: { fd6 = open(DEV_FILE_NAME6,00); if(fd6 < 0) { printf("Open device error\n"); return 0; } };
很显然第一个符号被替换了, 因为是符号是宏的缘故。 这样我们也能把这一扩展特性应用在变量上。
测试的话,可以用下面的代码来测试。
#include <stdio.h>
#define OPEN(a,b) {a#b} int main()
{
OPEN(cwd,);
OPEN(CWD,);
return ;
}
把其中的#换成#就是另外一个
另外注意 gcc -E 的好处
最新文章
- 利用扩展事件进行调优和Troubleshooting PPT分享
- Date, TimeZone, MongoDB, java中date的时区问题
- Ionic2学习笔记(6):Navigation
- (spring-第21回【MVC基础篇】)SpringMVC一点就通
- Retrofit2 + OkHttp3设置Http请求头(Headers)方法汇总
- 为CentOS 6 配置本地YUM源
- webservice远程调试开启
- JAVA:避免重复的创建对象
- Mysql 进阶操作
- 蚁群算法matlab实现
- BackGroundWorker使用总结
- webrtc底层一对一连接过程探索(三)
- spring 纯注解方式 与AOP
- Linux第四节课学习笔记
- centos7/RHEL7最小化系统安装gnome图形界面
- python定时发信息给女友
- 最短路(Bellman)-Hdu1874畅通工程序
- 整合Solr与tomcat以及第一个core的配置
- IDEA导包(以junit为例)
- core 文件查看
热门文章
- RH033读书笔记(13)-Lab 14 Network Clients
- 创建Material Design风格的Android应用--使用Drawable
- Minimum Sum LCM(uva10791+和最小的LCM+推理)
- 每天进步一点点--&;gt;函数fseek() 使用方法
- 自己主动机串标:Directed Acyclic Word Graph
- MySql分析算法作品索引(马上,只是说说而已B-tree)
- Visual Studio Team Services使用教程--邀请团队成员
- vs2015管理github代码
- Web Host消息处理管道
- opencv在arm和x86在移植