#include<stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{ printf("%s\n",h(f(,))); 宏h(a) 是g(a),没有#,所以需要进行宏展开
printf("%s\n",g(f(,))); //宏g(a) 有#,所以不展开
return ;
}

如何展开宏函数的规则:在展开当前宏函数时,如果形参有#或##则不进行宏参数的展开,否则先展开宏参数,再展开当前宏。

万能的stackoverflow

http://stackoverflow.com/questions/1686324/how-does-this-c-code-work
http://stackoverflow.com/questions/4364971/and-in-macros

http://zjf30366.blog.163.com/blog/static/411164582009061075923/

分析:

x##y把两个符号连起来   xy
#a指把a当成符号,就是把#后面的看成字符串

#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
printf("%s\n",h(f(1,2)));   //结果12
//因为h宏中的参数是另外一个宏,且带##,所以作为参数的宏不展开
printf("%s\n",g(f(1,2)));   //结果f(1,2)
//因为g宏中的参数是另外一个宏,但不带##,所以作为参数的宏先展开
在展开当前宏函数时,如果形参有#或##则不进行宏参数的展开,否则先展开宏参数,再展开当前宏。

C语言中的宏展开的更多相关文章

  1. C语言学习笔记--C语言中的宏定义

    1. C 语言中的宏定义 (1)#define 是预处理器处理的单元实体之一(因此,预处理器只是简单的进行替换,并不(2)#define 定义的宏可以出现在程序的任意位置(包括函数体的内部)(3)#d ...

  2. C\C++语言中的宏多重展开和递归展开

    宏定义中的#,## 1. 宏中的参数前面使用一个#,预处理器会把这个参数转换为一个字符数组     2.记号粘贴操作符(token paste operator): ##            “## ...

  3. C语言中的宏定义

    目录(?)[-] 简单宏定义 带参数的宏 运算符 运算符 宏的通用属性 宏定义中圆括号 创建较长的宏 较长的宏中的逗号运算符 宏定义中的do-while循环do 空操作的定义 预定义宏 C语言中常用的 ...

  4. C语言中的宏

    写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等.下面列举一些成熟软件中常用得宏定义...... 1,防止一个头文件被重复包含 #ifndef COMDEF_ ...

  5. 20个C语言中常用宏定义总结

    01: 防止一个头文件被重复包含 #ifndef COMDEF_H#define COMDEF_H//头文件内容#endif 02: 重新定义一些类型防止由于各种平台和编译器的不同,而产生的类型字节数 ...

  6. C语言中的宏总结

    宏定义分为两种: 1.变量式宏定义,如 #define abc def #define str "string" #define num 100 2.函数式宏定义, #define ...

  7. c语言中使用宏,需要注意的的几点

    使用#define来定义一些宏,进行一些简洁的替换甚至一些带参数的宏,在linux c代码中很常见,说明它很好.很有用, 但是它也有一些复杂的规矩和陷阱需要注意,下面我记录一些,仅供参考. 1.当使用 ...

  8. gcc将c源文件中的宏展开

    1: sudo gcc -P -I. -I../instrument/stubs -I../instrument/stubs -I../ -E ctrl_xfer32.cc -o preprocess ...

  9. Visual Studio属性配置中使用宏

    在学习C语言的时候,我们曾经遇到过一个宏的概念.宏的作用机理本质上是宏的展开,C语言中的宏的用法也有很多种(水其实很深...),不过从感觉上来讲,人们大致上会在以下的场景中,利用宏来解决一些窘境:一是 ...

随机推荐

  1. 【CocoaPods】配置CocoaPods前 - 本地安装好Ruby环境

    xcode (反正就是代码编辑器) Xcode就不用说了把. homebrew (反正就是软件管理器) homebrew是一个包管理器,用于在mac上安装一些os x上没有的UNiX工具(比如wget ...

  2. WPF中使用MVVM模式进行简单的数据绑定

    计划慢慢整理自己在WPF学习和工作应用中的一些心得和想法,先从一个简单的用法说起 在WPF中,XAML标记语言中绑定数据,而数据源就是指定为ViewModel类,而非界面本身的逻辑代码类 这样一定程度 ...

  3. c语言关于二进制的输出

    c语言中的二进制输出是没有占位符的,不像八进制:%o: 和十六进制:x%: c中二进制的输出 //右移31位,从最高为开始和1做&运算,得到每一位的二进制数值 void printbinry( ...

  4. Cookie 获取

    二级域名可以获取一级域名的Cookie值 二级域名下删除顶级域名下的Cookie,需要添加顶级域名的Cookie作用域 /// <summary> /// 根据cookie名称删除 /// ...

  5. SQL Server备份事务日志结尾(Tail)

    原文:http://blog.csdn.net/tjvictor/article/details/5256906   事务日志结尾经常提交数据库未备份的事务日志内容.基本上,每一次你执行事务日志备份时 ...

  6. eclipse中加放js文件报js语法错误解决办法

    1) eclipse设置         window->preference-> JavaScript -> Validator->Errors/Warnings->E ...

  7. IIS7.5 自定义Html/shtml/htm...后缀映射

    以添加html后缀的文件的 映射为例: 1.打开iis管理器,点击 2.点击打开处理程序映射 3.添加托管处理程序映射 4.请求路径 *.html 类型: System.Web.UI.PageHand ...

  8. 腾讯QQ企业邮箱在ruby on rails 框架中的mailer配置

    在编写ruby on rails程序时,我们可能会需要用到发送邮件的程序,如果使用gmail进行smtp发送一般问题不大,但很多企业使用的是腾讯QQ企业邮箱.使用该邮箱进行链接时出现各种错误,goog ...

  9. hadoop+hbase

    hadoop的配置见下面这篇文章 http://www.powerxing.com/install-hadoop-2-4-1-single-node/ Hadoop安装教程_单机/伪分布式配置_Had ...

  10. poj 2485 Highways(最小生成树,基础,最大边权)

    题目 //听说听木看懂之后,数据很水,我看看能不能水过 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stri ...