在C++开发当中经常用到宏的定义当中使用"#"或者"##",以下是对着两种符号使用方法的简单描述:

define中的#就是把#后面的参数当做一个符号来使用,简单的说就是把它当做字符串连接起来,##连接前后2个符号, define定义中以#开头的宏直接替换不展开,以非#开头的宏先展开再替换。

如下:

#define f(a,b) a##b

#define d(a) #a

#define s(a) d(a)

puts(d(f(a,b))); 输出结果: f(a,b)

puts(s(f(a,b))); 输出结果: ab

展开的过程如下:

puts(d(f(a,b))); ----> 因为d宏的定义以#开头,宏中的参数是另外一个宏,且带##,所以作为参数的宏不展开,相当于puts(#f(a,b));----->puts("f(a,b)");

puts(s(f(a,b))); ----> 因为s宏的定义不以#开头,宏中的参数是另外一个宏,但不带##,所以作为参数的宏先展开,相当于

puts(s(ab));----->puts(d(ab));---->puts(#ab);---->puts("ab");

综上所述有以下2中情况: 1.不以"#"开头的,先展开参数a,然后是替换代码:

puts(s(f(a,b)));-->puts(s(ab))-->puts(d(ab))-->puts("ab")

2.以"#"开头的,直接替换,不展开:

puts(d(f(a,b)))-->puts("f(a,b)")

C++宏定义中"#"与"##"的妙用的更多相关文章

  1. define宏定义中的#,##,@#及\符号

    define宏定义中的#,##,@#及\符号 在#define中,标准只定义了#和##两种操作.#用来把参数转换成字符串,##则用来连接两个前后两个参数,把它们变成一个字符串. 1.# (string ...

  2. 宏定义中的##操作符和... and _ _VA_ARGS_ _

    1.Preprocessor Glue: The ## Operator 预处理连接符:##操作符 Like the # operator, the ## operator can be used i ...

  3. 宏定义中使用do{}while(0)的好处 (转载)

    宏定义中使用do{}while(0)的好处   #define MACRO_NAME(para) do{macro content}while(0)   的格式,总结了以下几个原因:   1,空的宏定 ...

  4. C语言在宏定义中使用语句表达式和预处理器运算符

    语句表达式的亮点在于定义复杂功能的宏.使用语句表达式来定义宏,不仅可以实现复杂的功能,而且还能避免宏定义带来的歧义和漏洞.下面以一个简单的最小值的宏为例子一步步说明. 1.灰常简单的么,使用条件运算符 ...

  5. #define宏定义中## #@ # \ 符号使用

    C/C++ 宏命令的神奇用法. 先看下面三条语句: #define Conn(x,y)     x##y#define ToChar(x)     #@x#define ToString(x)    ...

  6. C语言宏定义中的#和##的作用【转】

    本文转载自:http://my.oschina.net/shelllife/blog/123202 在宏定义中#和##的作用是:前者将宏定义的变量转化为字符串:后者将其前后的两个宏定义中的两个变量无缝 ...

  7. C语言可变参数在宏定义中的应用

    在C语言的标准库中,printf.scanf.sscanf.sprintf.sscanf这些标准库的输入输出函数,参数都是可变的.在调试程序时,我们可能希望定义一个参数可变的输出函数来记录日志,那么用 ...

  8. C在宏定义中使用的语言可变参数

    于C标准库的语言,printf.scanf.sscanf.sprintf.sscanf入输出函数,參数都是可变的.在调试程序时.我们可能希望定义一个參数可变的输出函数来记录日志,那么用可变參数的宏是一 ...

  9. C/C++宏定义中#与##区别 .

    // #表示:对应变量字符串化// ##表示:把宏参数名与宏定义代码序列中的标识符连接在一起,形成一个新的标识符 #define U_BOOT_CMD_MKENT_COMPLETE(name,maxa ...

随机推荐

  1. 《Play for Java》学习笔记(五)Form

    本书第六章以一个实例介绍了Play Framework中Form的使用,如何绑定数据,如何进行验证 一.项目结构和action

  2. SQL 创建索引的作用以及如何创建索引

    SQL 创建索引的作用以及如何创建索引 SQL 创建索引的作用 一.使用索引的优点: 1.通过唯一性索引(unique)可确保数据的唯一性 2.加快数据的检索速度 3.加快表之间的连接 4.减少分组和 ...

  3. vs2016 vsto excel addin deploy error: vsto 无法解析属性type的值

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/ea33e391-21d7-4f54-92cb-c7af72f19c61/outlook- ...

  4. linux percona-toolkit的安装

    percona-toolkit是一套linux下的工具集,我们需要使用到 pt-query-digest 对mysql慢日志查询来做分析. 1.下载 http://www.percona.com/do ...

  5. Octopus系列之如何让前台的js脚本变得灵活重用

    Octopus系列如何让前台的js脚本变得灵活,重用 方式1:ajax方式 方式2:form表单方式 面向对象的脚本封装 jQuery的封装 做Web开发的少不了前台Ajax的使用, 返回true:f ...

  6. 一个简单的excel文件上传到数据库方法

    因为以前项目中有用到过Excel导入,所以整理了一下,这是一个导入Excel数据到数据库的方法 注意:需要导入poi jar包 代码清单 /** * Excel 导入 * @param mapping ...

  7. NetworkComms框架介绍 序列化并发送对象

    NetworkComms网络通信框架序言 英文原文:http://www.networkcomms.net/custom-objects/ NetworkComms.Net网络库,支持发送自定义类,并 ...

  8. (DFS)zoj1008-Gnome Tetravex

    现在zoj暂时关了,实际上是在scuoj上做的. 题目地址 看起来题目比较复杂,实际上主要需要思维的是如何恰当的剪枝及合适的DFS角度. 问题等价于将n*n个可能相同的方块放到一个n*n的表中,使满足 ...

  9. Windows8 10设置程序为 系统默认浏览器

    从win8 开始,MS修改了文件和协议的关联方式,普通的注册表修改是无效的. 必须使用组策略(group policy )对象GP才行. http://blogs.technet.com/b/mrml ...

  10. Excel公式中双引号和单引号输入和显示以及函数的选择确认

    [Excel中显示双引号] 1.直接输入双引号“”或单引号“ 2.工式中显示双引号需输入“”“”“”(六个引号)或单引号需输入“”“”(四个引号) [Excel中快速确认已选择的函数] 1.用键盘的上 ...