在C/C++的宏中,”#”的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。

而”##”被称为连接符(concatenator),用来将两个子串Token连接为一个Token。注意这里连接的对象是Token就行,而不一定是宏的变量。还可以n个##符号连接n+1个Token,这个特性是#符号所不具备的。

凡是宏定义里有用’#’或’##’的地方宏参数是不会再展开。

若要使’#’和’##’的宏参数被展开,可以加多一层中间转换宏。加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏就能得到正确的宏参数。

以下是测试代码:

#include "jinghao.hpp"
#include <iostream>//test1
#define WARN_IF(EXP) \if (EXP) \fprintf(stderr, "warning: "#EXP" \n");//test2
#define STR(s) #s//test3
#define _STRI(s) #s
#define STRI(s) _STRI(s) //转换宏//test4
#define paster(n) printf("token"#n" = %d\n", token##n)//test5
#define _CONS(a, b) int(a##+##b)
#define CONS(a, b) _CONS(a, b) //转换宏//test6
#define  _GET_FILE_NAME(f)   #f
#define  GET_FILE_NAME(f)    _GET_FILE_NAME(f)  //转换宏//test7
#define  _TYPE_BUF_SIZE(type)  sizeof #type
#define  TYPE_BUF_SIZE(type)   _TYPE_BUF_SIZE(type) //test8
#define D(x)  #@x  //仅对单一标记转换有效int test_jinghao1()
{//test1int divider = 0;WARN_IF(divider == 0);// warning: divider == 0//test2printf("int max: %s\n", STR(INT_MAX));// int max: INT_MAX//test3printf("int max: %s\n", STRI(INT_MAX));// int max: 2147483647//test4int token9 = 9;paster(9);// token9 = 9//test5int A = 15, B = 2;printf("A + B = %d\n", CONS(A, B));// A + B = 17//test6char  FILE_NAME[] = GET_FILE_NAME(__FILE__);std::cout << FILE_NAME << std::endl;// "..\\..\..\\demo\\CppBaseTest\\jinghao.cpp"//test7std::cout << TYPE_BUF_SIZE(INT_MAX) << std::endl;// 11//test8std::cout << D(F) << std::endl;//Freturn 0;
}#define CHECK_PARAMS(condition, ret)           \{if (!(condition)) {                       \fprintf(stderr, "Error: "#condition"  %d\n", ret); \return ret;}}int test_jinghao2()
{int* param1 = nullptr;CHECK_PARAMS(param1, -1);// Error: param1 -1return 0;
}

以上内容整理自:

1.      http://keendawn.blog.163.com/blog/static/888807432011527113124144/

2.      http://www.cppblog.com/just51living/archive/2011/08/08/152752.html

3.      http://blog.csdn.net/acs713/article/details/6891837

C/C++中“#”和“##”的作用和用法相关推荐

  1. python 中/ 与 //的作用、用法

    python 中/ 与 //的作用.用法 原创蓝莓·山药 最后发布于2019-06-21 09:27:54 阅读数 3591  收藏 展开 python语法中, / 是除法,例如:2/3 = 0.66 ...

  2. MySQL数据类型中DECIMAL的作用和用法

    在MySQL数据类型中,例如INT,FLOAT,DOUBLE,CHAR,DECIMAL等,它们都有各自的作用,下面我们就主要来介绍一下MySQL数据类型中的DECIMAL类型的作用和用法. 一般赋予浮 ...

  3. Vue 中的 v-cloak 作用及用法

    v-cloak 的作用和用法 用法: 这个指令保持在元素上直到关联实例结束编译.和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Must ...

  4. 深入理解C# 中 “$” 符号的作用以及用法

    前言:$是c# 6.0 的语言特性,功能类似string.format(),更方便的地方在于不要像format一样使用索引,可以直接使用变量.表达式或者方法的执行. 文章目录 一.C#中`$`的作用 ...

  5. SpringMVC中 -- @RequestMapping的作用及用法

    一.@RequestMapping 简介 在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.x ...

  6. springMVC中的ModelMap作用及用法

    概念 ModelMap的作用: ModelMap对象主要用于传递控制方法传递数据到结果页面.类似于request的setAttribute方法的作用. 所以我们要想在jsp页面获取数据,只要将数据放到 ...

  7. Vue 中的 v-cloak 作用及用法-vue页面加载时会闪烁

    用法: 这个指令保持在元素上直到关联实例结束编译.和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕 ...

  8. Java中volatile的作用以及用法

    volatile让变量每次在使用的时候,都从主存中取.而不是从各个线程的"工作内存". volatile具有synchronized关键字的"可见性",但是没有 ...

  9. rono在oracle的作用_Oracle中存储过程的作用和用法

    存储过程是Oracle开发者在数据转换或查询报表时经常使用的方式之一.它就是想编程语言一样一旦运行成功,就可以被用户随时调用,这种方式极大的节省了用户的时间,也提高了程序的执行效率.存储过程在数据库开 ...

  10. C++ 中explicit的作用及用法(虽然简单,但是还是有用的)

    目录 C++explicit(官网的说法) explicit specifier C++explicit 清楚的说法(建议英文不好的从这里开始食用哦) explicit作用: explicit使用注意 ...

最新文章

  1. boost::math::legendre_stieltjes用法的测试程序
  2. c++primer练习13.42
  3. python中的单继承,多继承和mro顺序
  4. 重大革新!Dubbo 3.0来了
  5. strictmath_Java StrictMath rint()方法与示例
  6. 菜鸟的成长记录--linux 通配符和特殊字符集合的使用
  7. 搭建你的持续集成server - CruiseControl step by step(1)
  8. easyui之treegrid的生成
  9. php 苹果支付验证,PHP实现Apple应用内购服务端验证
  10. 手把手教你开发基于单片机的wifi通信的物联网项目(远程灯控制)
  11. 华为人均工资高达70万,但先看看华为员工的16项标准
  12. Vue 自定义移动端的 滑动事件
  13. 网络编程学习路线计划
  14. php 开源系统(cms),30个很棒的PHP开源CMS内容管理系统
  15. [人工智能-深度学习-46]:FineTuning(微调)、Transfer Trainning(迁移学习)的理论基础与深度解析
  16. 极米和当贝投影仪应该怎样抉择?一文告诉你答案
  17. 禁止浏览器对页面进行缩放
  18. 用过Retina视网膜屏幕的笔记本电脑的后果
  19. 写段小程序,为自己的配置加个密
  20. android eclipse加密,Elliptic Curve Cryptography:在eclipse android中使用NFC发送加密消息

热门文章

  1. c++成员函数的重载、覆盖、隐藏区别
  2. Python Qt GUI设计:QSlider滑动条类(基础篇—16)
  3. TensorFlow实现一元线性模型
  4. windows/linux计算文件 MD5值
  5. 如何学习streamdecoder类_如何学习篇5:强化2种能力——2种学习模式之运动类:隐性学习...
  6. 【实现手机端上滑滚动加载列表】判断页面是否滚动到底部或者指定元素位置
  7. 不相交集类以及应用迷宫生成
  8. VOLTE parameter in Attach Request/Accept message
  9. Java虚拟机垃圾收集算法
  10. 图的算法专题——最小生成树