参考自: http://zjf30366.blog.163.com/blog/static/411164582009061075923/

#include<cstdio>

#include<iostream>

using namespace std;

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

#define d(a) #a

#define s(a) d(a)

int main()

{

    int xy = 10;

    cout<< f(x,y) << endl;

    puts( d(f(a,b));

    puts( s(f(a,b) );

}

输出

10

f(a,b)

ab

分析:

1 # 和 ## 操作符是和#define宏使用的. # 使在#后的首个参数返回为一个带引号的字符串; ##把两个符号连起来是把##前后两个符号连接起来

2 第一行输出没有什么好解释的,后两行输出我看网上有两种解释

(1)从##角度解释

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)从#角度解释

#define f(a,b) a##b 
#define d(a) #a --》 以"#"开头的,直接替换,不展开:immediately replaced by the unexpanded actual argument 
#define s(a) d(a) --》 非以"#"开头的,先展开,再替换,也就是一般的情况

所以就两种情况: 
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)")

#define中 #与##用法的更多相关文章

  1. #define中 #与##的神奇用法linux学习 (转)

    #define中 #与##的神奇用法linux学习 (转) #define f(a,b) a##b #define d(a) #a #define s(a) d(a) void main( void ...

  2. c/c++头文件中#ifndef/#define/#endif的用法

    想必很多人都看过“头文件中用到的 #ifndef/#define/#endif 来防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?头文件被重复引用了,会产生什么后果?是不是所有的头文 ...

  3. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  4. #ifndef#define#endif的用法

    在网上看到了感觉作者总结得很好,作者辛苦了! #ifndef#define#endif的用法 文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都 ...

  5. #ifndef#define#endif的用法(整理)

    [转] #ifndef#define#endif的用法(整理)    原作者:icwk  文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都in ...

  6. Oracle 变量 之 define variable declare 用法及区别

    Oracle 变量 之 define variable declare 用法及区别 Table of Contents 1. 扯蛋 2. define和accept 3. variable 3.1. ...

  7. ORACLE 中ROWNUM用法总结(转)

    ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...

  8. AngularJS select中ngOptions用法详解

    AngularJS select中ngOptions用法详解   一.用法 ngOption针对不同类型的数据源有不同的用法,主要体现在数组和对象上. 数组: label for value in a ...

  9. c#初学-多线程中lock用法的经典实例

    本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被 ...

随机推荐

  1. 网页引用google字体速度慢:fonts.googleapis.com

    由于众所周知的原因,国内使用google font库有很大的问题. 使用国内镜像如360网站卫士常用前端公共库CDN服务 http://libs.useso.com/ 优点:使用方便 缺点:目标用户包 ...

  2. java的覆盖重写隐藏和C#中的不同

    先看下C#中的: C#中覆盖 隐藏 重写这三种有不同的意义,而Java中不同. 1. java中没有new ,使用new会报错,编译不通过. 2. java中重写和覆盖应该是一个意思 static c ...

  3. 廖雪峰Python教程疑问

    1. 字符串的strip()方法 原文: “把一个序列中的空字符串删掉,可以这么写: def not_empty(s): return s and s.strip() list(filter(not_ ...

  4. gulp基本用法

    嗨,小伙伴们,大家周五好,又到了一周中最最最期待的周五啦啦~~~ 这几天一直在研究gulp的使用方法,今天抽时间来整理一下基本步骤. gulp 的使用流程: 安装nodejs ->安装git(方 ...

  5. Weblogic新增域(可以配置新端口)

    操作系统 :Linux version 2.6.32-504.el6.x86_64 Weblogic Server :11g 一.Weblogic新增域(可以配置新端口) 以weblogic用户登录 ...

  6. URL参数为url,获取不到部分参数问题

    url1中的参数含有url2,在页面上获取url时发现url后面跟的参数获取不到,其实是浏览器把url2中&后的参数作为url1的参数来处理了. 如:http://www.ilcng.com/ ...

  7. 转载《Android LayoutInflater详解》

    在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例 ...

  8. linux 模块常用命令

    lsmod | grep pcspkr  查看pcspkr模块是否运行modprobe -r pcspkr   删除pcspkr模块modinfo pcspkr       查看pcspkr模块信息m ...

  9. 从Eclipse转移到IntelliJ IDEA一点心得

    http://www.ituring.com.cn/article/37792 本人使用IntelliJ IDEA其实并不太久,用了这段时间以后,觉得的确很是好用.刚刚从Eclipse转过来的很多人开 ...

  10. Unicode 和 UTF-8 的关系

    曾经这个世界上,有着gb2312,gbk,latin1,utf 等各种字符集,现在,我们也能不时的看到他们的身影. 但是值得庆幸的事,时过境迁,这些主要的字符集,都已经逐渐被utf8取代. 但是我们很 ...