原文在这里

宏参数

function-like宏可以带参数,就好像函数带参数一样。定一个一个带参数宏的时候,把参数插入到两个括号之间,就好像定义函数的参数一样。这就是该类宏被称为function-like宏的原因。宏参数必须是合法的C标识,由逗号和空格隔开。

调用带参数的宏,你可以在写完宏名之后插一对括号,然后在括号里跟实参,由逗号隔开。宏调用的代码并不是必须写在一行里,你可以想写多少行就写多少行。实参的数目必须符号定义时参数的数目。宏展开时,宏内容里的参数会自动被实参内容替代。(并不是所有的参数都必须在宏内容里出现。)

举个例子,这里有一个宏,作用是计算两个数值中较小的那一个,c语言的代码里常出现这样的宏

     #define min(X, Y)  ((X) < (Y) ? (X) : (Y))x = min(a, b);          ==>  x = ((a) < (b) ? (a) : (b));y = min(1, 2);          ==>  y = ((1) < (2) ? (1) : (2));z = min(a + 28, *p);    ==>  z = ((a + 28) < (*p) ? (a + 28) : (*p));
(在这个小宏里面,你已经可以看到很多带参数宏的危险,详情请看宏的陷阱)
起始的和末尾的空格会被虑掉,两个记号之间的所有空格都会被替换成一个空格。每个参数间的括号必须配对;括号内的逗号不会结束语句。然而,中括号和大括号则不必配对,并且中括号或大括号内的逗号会被当成是分割两个参数的记号,所以
     macro (array[x = y, x + 1])
解析出了两个参数:array[x = y, 以及x + 1]。如果你想要的结果是把array[x=y, x+1]整个当成参数,那么你就得这样写:array[(x=y, x+1)]。
所有的宏参数都在替换到宏内容之前展开。替换了之后,完整的内容又被扫描一遍,以便宏内容包括参数本身被展开。这条规则看上去很奇怪,但它是仔细设计过的,这么做的结果就是,你完全不必关心你调用的到底是函数还是宏。实际上如果你想在这点上表现的聪明点,结果反而会很糟。参看参数预扫描获取更多的细节。
举个例子,min (min (a, b), c)首先被展开成
 min (((a) < (b) ? (a) : (b)), (c))
然后展开成
     ((((a) < (b) ? (a) : (b))) < (c)? (((a) < (b) ? (a) : (b))): (c))
(这里的分行只是为了看着方便,不是真的会展开成分行的代码)
你可以把宏参数留空,预处理器不会认为这是个错误(但是很多宏会展开成不合法代码)。但是你不能完全不管参数。如果一个宏带两个参数,参数列表的顶层必须只能有一个逗号
     min(, b)        ==> ((   ) < (b) ? (   ) : (b))min(a, )        ==> ((a  ) < ( ) ? (a  ) : ( ))min(,)          ==> ((   ) < ( ) ? (   ) : ( ))min((,),)       ==> (((,)) < ( ) ? ((,)) : ( ))min()      错误,min宏要求两个参数,但这里只有一个参数
min(,,)    错误,min宏里面传入了3个参数,但实际只需要两个
空格不是预处理符号,所以如果宏foo带一个参数,foo  ()和foo  (   )都提供给宏一个空参数。之前的GNU预处理器对这一点的实现和文档都是错误的。
字符常量里出现的宏参数名不会展开:
#define foo(x) x, "x"
foo(bar)        ==> bar, "x"
 

转载于:https://www.cnblogs.com/gussing/archive/2008/10/20/1315357.html

c语言里的宏(翻译)4相关推荐

  1. C语言里的“宏”是指什么?

    简单来说:宏定义又称为宏代换.宏替换,简称"宏".是C提供的三种预处理功能的其中一种.复杂的请看下面,讲的很全.下面的带参宏定义,多行宏定义,在Linux内核源码中很多.另外siz ...

  2. 为什么除了Go语言, 其他类C语言都是垃圾[翻译][转]

    2019独角兽企业重金招聘Python工程师标准>>> 英文原文: http://www.syntax-k.de/projekte/go-review 原始翻译: http://ww ...

  3. 在物理学的语言里,“生命”是什么?

    转自:Darthusian "想象一种语言就像想象一种形式的生命." --- 路德维希.维特根斯坦,<哲学研究> 当今世界人们使用大约6,800种不同的语言.不是每个词 ...

  4. c语言关键词中英翻译机编程,C语言关键字中英翻译机.doc

    C语言关键字中英翻译机 中 北 大 学 课程设计报告 学 院.系:软件学院专 业:软件工程学 生 姓 名:学 号:设 计 题 目:C语言关键字中英翻译机 起 迄 日 期: 2011年5月30日~ 20 ...

  5. c语言printf的%f语句,在C语言里printf是什么意思怎么

    在C语言里printf是什么意思?怎么用?? 1,printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息. 2,printf()函数的调用格式为: printf(" ...

  6. c语言关键字中英翻译机课程设计,C语言关键字中英翻译机.doc

    C语言关键字中英翻译机.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3.该文档 ...

  7. c语言define n 3,C语言里#define N 10是什么意思

    C语言里"#define N 10"是表示之后代码中的"N"全部代表"10",并且是在执行编译预处理时就进行了实际的替换操作. define ...

  8. ebnf描述c语言语句结构,EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则...

    Presentation on theme: "EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构:并用操作语义的方法描述对应的语义规则"- Pre ...

  9. 全球首个突破200种语言互译的翻译引擎,百度翻译打破世界沟通壁垒

    机器翻译作为人工智能关键技术之一,正日益成为企业智能化升级的重要应用场景.12月1日,百度大脑开放日举办了以"机器翻译 沟通全世界"为主题的专场活动. IDC 中国副总裁兼首席分析 ...

最新文章

  1. 链家秋招内推编程笔试题目
  2. SLF4J 教程(自由在各种log中切换)
  3. 用JS实现发邮件的功能 完美解决
  4. PngEncoder_CreateInstance Failed writing PNG because unable to find libpng12.so.0
  5. 陈百强原来这么帅_朱一龙虽然很少玩手机,但居式打字法很有个性,手指飞舞超级帅!...
  6. php中的缓,php中的缓存机制解释
  7. 方正高影仪安装方法_铝合金门窗是怎么安装的?
  8. Flutter拓展 android studio如何连接夜神模拟器(亲测!!!)
  9. Python进阶(七)argparse参数解析
  10. js获取地址栏的各种信息(location)
  11. ARM基础学习-寄存器寻址方式和指令
  12. excel取消隐藏_Excel教程:教你两招,批量取消隐藏工作表
  13. 第十二节 JS事件高级应用
  14. Cathy Zhang automation test
  15. 使用sqlplus创建表空间
  16. 百度网盘提速法,不用插件,不用安装脚本
  17. 【Java基础】【案例】
  18. 11 系统建模语言SysML实例——蒸馏器
  19. oracle补位函数 不足位数补0
  20. 【面试题】755- 104道 CSS 面试题,助你查漏补缺(上)

热门文章

  1. 实现strlen()(c语言)
  2. mac https本地跨域配置
  3. 关于KernelFaultCheck启动项
  4. 对CAN、USART、SPI、SCI等常见总线的简单介绍
  5. DOS系统功能调用表(INT 21H)
  6. 汇编指令CALL与JMP的区别
  7. hihoCoder #1457 : 后缀自动机四·重复旋律7
  8. matlab中对伺服电机,基于Matlab的伺服电机Modbus通讯研究
  9. allocator类初学的简单例子
  10. tar.gz 文件类型(tar文件的解压和压缩)