C++/C宏定义中## 连接符与# 符的含义

http://blog.163.com/wshyao@126/blog/static/1070451420081018103237836/

## 连接符与# 符

  ## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释,但不知道也无所谓。同时值得注意的是#符是把传递过来的参数当成字符串进行替代。下面来看看它们是怎样工作的。这是MSDN上的一个例子。

  假设程序中已经定义了这样一个带参数的宏:

#define paster( n ) printf( "token" #n " = %d", token##n )

  同时又定义了一个整形变量:

int token9 = 9;

  现在在主程序中以下面的方式调用这个宏:

paster( 9 );

  那么在编译时,上面的这句话被扩展为:

printf( "token" "9" " = %d", token9 );

  注意到在这个例子中,paster(9);中的这个”9”被原封不动的当成了一个字符串,与”token”连接在了一起,从而成为了token9。而#n也被”9”所替代。

  可想而知,上面程序运行的结果就是在屏幕上打印出token9=9 

 

http://kenshinf.blog.51cto.com/1088256/252541

关于记号粘贴操作符(token paste operator): ##
1. 简单的说,“##”是一种分隔连接方式,它的作用是先分隔,然后进行强制连接
其中,分隔的作用类似于空格。我们知道在普通的宏定义中,预处理器一般把空格
   解释成分段标志
,对于每一段和前面比较,相同的就被替换。但是这样做的结果是,
   被替换段之间存在一些空格。如果我们不希望出现这些空格,就可以通过添加一些
   ##来替代空格
另外一些分隔标志是,包括操作符,比如 +, -, *, /, [,], …,所以尽管下面的
   宏定义没有空格,但是依然表达有意义的定义: define add(a, b)  a+b
而其强制连接的作用是,去掉和前面的字符串之间的空格,而把两者连接起来。
2. 举列 – 试比较下述几个宏定义的区别
#define A1(name, type)  type name_##type##_type 或
   #define A2(name, type)  type name##_##type##_type
A1(a1, int);  /* 等价于: int name_int_type; */
   A2(a1, int);  /* 等价于: int a1_int_type;   */
解释:
        1) 在第一个宏定义中,”name”和第一个”_”之间,以及第2个”_”和第二个
   ”type”之间没有被分隔,所以预处理器会把name_##type##_type解释成3段:
   “name_”、“type”、以及“_type”,这中间只有“type”是在宏前面出现过
    的,所以它可以被宏替换。
2) 而在第二个宏定义中,“name”和第一个“_”之间也被分隔了,所以
   预处理器会把name##_##type##_type解释成4段:“name”、“_”、“type”
   以及“_type”,这其间,就有两个可以被宏替换了。
3) A1和A2的定义也可以如下:
           #define A1(name, type)  type name_  ##type ##_type  
                                      <##前面随意加上一些空格>
           #define A2(name, type)  type name ##_ ##type ##_type
结果是## 会把前面的空格去掉完成强连接,得到和上面结果相同的宏定义
3. 其他相关 – 单独的一个 #
至于单独一个#,则表示 对这个变量替换后,再加双引号引起来。比如
#define  __stringify_1(x)   #x
那么
      __stringify_1(linux)   <==>  ”linux”
所以,对于MODULE_DEVICE_TABLE
1) #define MODULE_DEVICE_TABLE(type,name)                        
             MODULE_GENERIC_TABLE(type##_device,name)
     2) #define MODULE_GENERIC_TABLE(gtype,name)                      
             extern const struct gtype##_id __mod_##gtype##_table     
             __attribute__ ((unused, alias(__stringify(name))))
得到  
      MODULE_DEVICE_TABLE(usb, products)  
                             /*notes: struct usb_device_id products; */
 <==> MODULE_GENERIC_TABLE(usb_device,products)
 <==> extern const struct usb_device_id __mod_usb_device_table     
             __attribute__ ((unused, alias(”products”)))   
注意到alias attribute需要一个双引号,所以在这里使用了__stringify(name)来
给name加上双引号。另外,还注意到一个外部变量”__mod_usb_device_table”被alias
到了本驱动专用的由用户自定义的变量products<usb_device_id类型>。这个外部变量
是如何使用的,更多的信息请参看《probe()过程分析》。
4. 分析方法和验证方式 – 编写一个简单的C程序
用宏定义一个变量,同时用直接方式定义一个相同的变量,编译报告重复定义;
   用宏定义一个变量,直接使用该宏定义的变量名称,编译通过且运行结果正确;
   使用printf打印字符串数据。printf(”token macro is %s”, __stringify_1(a1));

 

 

转载于:https://www.cnblogs.com/xuxm2007/archive/2011/06/10/2077255.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

揭秘|多伦多大学反人脸识别,身份欺骗成功率达99.5%

来源 &#xff1a;机器人大讲堂摘要&#xff1a;在一些社交媒体平台&#xff0c;每次你上传照片或视频时&#xff0c;它的人脸识别系统会试图从这些照片和视频中得到更多信息。比如&#xff0c;这些算法会提取关于你是谁、你的位置以及你认识的其他人的数据&#xff0c;并且&am…

安卓逆向_8 --- Android 调试工具 DDMS 和 Monitor ( 去掉 车来了 app 的广告 )

From&#xff1a;https://www.e-learn.cn/topic/3527658 Android SDK 中的 ddms 使用详解&#xff1a;https://blog.csdn.net/x83853684/article/details/80643131 ADB、Android Monitor、DDMS、HierarchyViewer、MAT、SysTrace、TraceView 性能分析工具使用大全&#xff1a;…

杂谈 | 微软复兴,它与苹果竟有这么多相似之处!

来源&#xff1a;网易智能摘要&#xff1a;且不要谈CEO们是否会让他们公司的“重生”&#xff0c;仅仅是成为一个成功帝国的好管家就已经是一项了不起的成就了。上周&#xff0c;微软市值超过了谷歌母公司Alphabet&#xff0c;成为继苹果&#xff08;Apple&#xff09;和亚马逊…

全能终端神器 --- MobaXterm 、开启 linux 远程桌面

From&#xff1a;https://cloud.tencent.com/developer/news/244102 官网地址&#xff1a;https://mobaxterm.mobatek.net MobaXterm 20.2_Professional.7z 下载地址&#xff1a;https://download.csdn.net/download/freeking101/12363312 MobaXterm 又名 MobaXVT&#xff0c…

强势~帮不了别人,也不用内疚

妻子的控诉 妻子&#xff1a;“你要是再让我生气&#xff0c;咱们就离婚。” 这种想法会让对方产生负疚感&#xff0c;因为言下之意是&#xff0c;婚约和两人之间的关系&#xff0c;要比夫妻双方的个人意愿和幸福更重要。 丈夫&#xff1a;“要是你确实觉得受不了&#xff0c…

【转】盛大创新院许式伟:影响我一生的五个重要选择

盛大创新院许式伟&#xff1a;影响我一生的五个重要选择 资料来源&#xff1a;http://www.programmer.com.cn/4206/ 作者&#xff1a; wuzhimin分类&#xff1a;坊间人语阅读&#xff1a;40,227 次添加评论文 / 许式伟 每个人的际遇是不同的&#xff0c;面临选择时&#xff0c;…

安卓逆向_7 --- 六种快速定位关键 Smali 代码的方法 ( 去掉 RE 广告 )

哔哩哔哩&#xff1a;https://www.bilibili.com/video/BV1UE411A7rW?p34 具体用法&#xff0c;看视频教程&#xff08; 去掉 RE 的 结束广告 &#xff09; 6 种定位关键代码的方法&#xff0c;当然还有其他方法&#xff0c;以后遇见了补充上&#xff1a; 1. 信息反馈法&#…

教机器遗忘或许比学习更重要:让AI健忘的三种方式

大数据文摘出品编译&#xff1a;臻臻、Shan LIU、龙牧雪大部分人不会喜欢遗忘的感觉。回到家顺手把钥匙丢在一个角落就再也想不起来放在哪儿了&#xff0c;街角偶遇一个同事却怎么拍脑袋也叫不出他的名字……我们害怕遗忘&#xff0c;讨厌遗忘。然而&#xff0c;生而为人&#…

代码精进之路~自明的代码

中间变量 Matcher matcher headerPattern.matcher(line); if (matcher.find()) {headers.put(matcher.group(1), matcher.group(2)); } 优化后 Matcher matcher headerPattern.matcher(line); if (matcher.find()) {String key matcher.group(1);String value matcher.g…

OpenCV图像或视频显示在VC对话框中的方法

转自&#xff1a;我思故我在 在MFC界面上添加一个picture控件&#xff0c;假设其ID为IDC_STATIC_PIC&#xff0c;类型设置为"增强图元文件" 首先包含OPENCV里的头文件&#xff1a; #include <cv.h> #include <stdio.h> #include <highgui.h> 在相应…

一套价值十万的微信公众号采集解决方案

From&#xff1a;http://www.blog2019.net/post/138 原文地址 相关阅读&#xff1a; 一套价值十万的微信公众号采集解决方案(免费送) 数据采集采集架构中各模块详细分析 基于大数据平台的互联网数据采集平台基本架构 教你一种1分钟下载1万个网页的方法&#xff0c;你学吗&a…

2018 年全球人工智能与机器人峰会将在深圳举办

来源&#xff1a;雷锋网摘要&#xff1a;第三届 CCF-GAIR —— 2018 年全球人工智能与机器人峰会&#xff0c;深圳&#xff0c;2018 年 6 月 29 日至 7 月 1 日。2018 年&#xff0c;AI 学术界与工业界的核心议题已演变为“基础理论技术创新”和“行业解决方案落地”&#xff0…

ASP.NET使用数据库存储、读取并修改图片

在SQL SERVER中建立这样结构的一个表&#xff1a;列名类型目的IDInteger主键IDIMGTITLEVarchar(50)图片的标题IMGTYPEVarchar(50)图片类型. ASP.NET要以辨认的类型IMGDATAImage用于存储二进制数据 using System;using System.Collections;using System.Configuration;using…

Grafana 使用教程 --- 开源的度量分析与可视化套件

原文链接&#xff1a;https://blog.csdn.net/bbwangj/article/details/81109615 Linux下使用GrafanaInfluxDBMongoDB实现爬虫可视化动态监控【附代码及详细教程】 https://www.jianshu.com/p/9de223e05a5e Grafana是一个开源的度量分析与可视化套件。经常被用作基础设施的时间…

美国重夺超算“头把交椅”,专家建议中国加快E级超算研制

“顶点”超算 橡树岭国家实验室网站图来源&#xff1a;科技日报摘要&#xff1a;美国能源部下属橡树岭国家实验室6月8日正式宣布&#xff0c;已研发出被命名为“顶点”的超级计算机。美国能源部下属橡树岭国家实验室6月8日正式宣布&#xff0c;已研发出被命名为“顶点”的超级计…

安卓逆向_9 --- log 插桩、Toast 弹窗、smali代码编写和植入 ( 好搜小说 )

From&#xff1a;https://www.bilibili.com/video/BV1UE411A7rW?p36 如果仅仅用 Smali 来分析代码&#xff0c;效果其实不如用 dex2jar 和 jd-gui 更直观&#xff0c;毕竟看反编译的 java 代码要更容易一些。 但 Smali 强大之处就是可以随心所欲的进行插桩操作。何为插桩&…

调试opengl程序出错

今天要做opengl实验 打开一个示例程序&#xff0c;结果编译不过。错误大概如下&#xff1a; d:\vc98\include\gl\gl.h(1152) : error C2054: expected ( to follow WINGDIAPI d:\vc98\include\gl\gl.h(1152) : error C2085: APIENTRY : not in formal parameter list d:\vc98\i…

代码精进之路~函数

职责单一 一个方法只做一件事情。 eg.给员工发工资 public void pay(List<Employee> employees) {for (Employee e : employees) {if (e.isPayDay()) {Money pay e.calculateDay();e.deliverDay(pay);}}} 实际上做了3件事&#xff1a;遍历所有雇员、检查是否该发工资…

智能哲学:“学习机器”与“机器学习” ——解读图灵思想中的人工智能

周剑铭&#xff0c;自由学者。研究方向为中西文化比较研究&#xff0c;智能哲学&#xff0c;算法、不确定性和不确定性问题(NP)理论。柳渝&#xff0c;法国儒勒凡尔纳公立综合大学计算机&#xff08;Dpartement Informatique, UFR des Sciences, Universit de Picardie Jules V…

【分享】关于对象关系映射的理解

对象关系映射&#xff08;Object Relational Mapping&#xff0c;简称ORM&#xff09;是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说&#xff0c;ORM是通过使用描述对象和数据库之间映射的元数据&#xff0c;将java程序中的对象自动持久化到关系数…