①一个较长的宏定义可以分成若干行,这需要在待续的行末尾加上一个反斜杠符”\”

#define TUP_ASSERT(__expression) do {\

if (!( __expression )) \

{ \

SYSLOG_LEGACY(EAaSysLogSeverityLevel_Error,"<TUP ASSERTION FAILED> (%s) file: %s line:%u", #__expression,__FILE__, __LINE__); \

AaErrorAssertion(#__expression,__FILE__, __LINE__); \

} \

} while(0)

②在替换文本中,参数名以#作为前缀则结果将被扩展为由实际参数替换该参数的带引号的字符串

#define dprint(expr) printf(#expr “ =%g\n”, expr)

使用语句dprint(x/y),该宏将被扩展为

printf(“x/y” “= %g\n”, x/y);

③预处理运算符##为宏展开提供参数连接的作用

#define paste(front, back) front ##back

宏调用paste(name,1)的结果将建立记号name1

④宏展开顺序大致可以归结为:

第一步:首先用实参代替形参,将实参代入宏文本中

第二步:如果实参也是宏,则展开实参

第三步:最后继续处理宏替换后的宏文本,如果仍包含宏,则继续展开

注意:如果在第二步,实参代入宏文本后,实参之前或之后遇到#或##,实参不再展开

例1:

#define cat(a,b) a ## b

宏调用:cat(cat(1, 2), 3) 的展开顺序为:

cat(cat(1, 2), 3) -->cat(1, 2) ## 3  -->cat(1, 2)3

cat(1,2)仍是宏,但后面是##,不再展开,结果为:cat(1, 2)3

例2:

#define cat(a,b) a ## b

#define xcat(x, y) cat(x, y)

宏调用 xcat(xcat(1, 2), 3) 的展开顺序为:

xcat(xcat(1,2), 3) -->cat(xcat(1, 2), 3) -->cat(cat(1, 2), 3) -->cat(1 ## 2, 3) --> 1 ##2 ## 3 -->123

务必注意参数的处理顺序,第二步在第三步前面执行,第一层宏展开后,实参是宏,则首先处理实参的宏展开,即使宏替换后本身也是宏。在例2中,虽然也生成的cat(cat(1, 2), 3),但是是首先执行里面的cat(1, 2), 所以结果不一样。例2中以下顺序是错的:

xcat(xcat(1,2), 3) --> cat(xcat(1, 2), 3) --> xcat(1, 2) ## 3 -->xcat(1, 2)3

在Linux测试结果:

使用gcc –E 编译可以只做预处理:源文件hepeng.c:

*****************************************************************************

#define cat(a,b) a ## b

#define xcat(x,y) cat(x,y)

int  main()

{

   cat(cat(1,2),3);

   xcat(xcat(1,2),3);

   xcat(cat(1,2),3);

    return 0;

}

*****************************************************************************

[penhe@hzling23 program]$gcc -E hepeng.c |more

*****************************************************************************

# 1 "hepeng1.c"

# 1 "<built-in>"

# 1 "<command line>"

# 1 "hepeng1.c"

int main()

{

    cat(1,2)3;

    123;

    123;

    return 0;

}

*****************************************************************************

C语言的宏定义、宏展开相关推荐

  1. c语言 宏定义 宏用法

    目录 #define  标识符  常量 1.#if系列用法 2.#ifdef用法 3.#ifndef用法 4.#error用法 #define  标识符  常量 C语言中,可以用 #define 定义 ...

  2. java中宏定义,宏定义的使用

    C中的宏分为两类,对象宏(object-like macro)和函数宏(function-like macro). 预定义宏: 1.预定义宏的行为是由编译器指定的. 2.前后双下杠的一般都是预定义. ...

  3. C语言中宏定义宏编译的使用#if,#ifdef,#ifndef,#elif,#else,#endif,defined使用详解,可以实现和if else一样的效果

    #define            定义一个预处理宏 #undef            取消宏的定义 #if                   编译预处理中的条件命令,相当于C语法中的if语句 ...

  4. java define 宏_宏定义宏函数(日志输出)define

    最常见的就是 #indef __cplusplus 这表示支持C++语法 再如可以定义常量 #define MAX 100 这跟JAVA全局变量有什么区别呢? JAVA的变量是有类型的,这没有类型,这 ...

  5. 宏定义宏函数 if else语句报错:error: ‘else’ without a previous ‘if’(看似解决实际上没解决)

    代码 #include <stdio.h> #include <stdlib.h>#define ALOGE(...) { printf(__VA_ARGS__); print ...

  6. 如何用C语言改变宏定义的大小,C语言中宏定义使用的小细节

    C语言中宏定义使用的小细节 #pragma#pragma 预处理指令详解 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#p ...

  7. C/C++编程笔记:浅析 C 语言中宏定义的使用,知识点全解

    宏定义是用一个标识符来表示一个字符串,在宏调用中将用该字符串代替宏名.给程序员提供了便利,使程序更加清晰,便于阅读和理解,进一步提高了程序的运行效率,对于嵌入式系统而言,为了能达到性能要求,宏是一种很 ...

  8. c语言 宏定义 条件,c语言宏定义、条件编译

    笔记整理: 宏定义 宏定义的一般形式为: #define 宏名 字符串或者表达式 预处理的工作就是替换,就是将宏名替换成相应的字符串与表达式. 宏定义字符串: #define 宏名 字符串 该示例中的 ...

  9. C语言宏定义方法总结

    转载:http://blog.csdn.net/qustdjx/article/details/7907173 补充一种超级强大的宏定义方式:这种方式的宏不会受到括号,冒号极端情况的影响,比单纯加() ...

  10. 【C语言】宏定义和带参宏定义

    宏定义是在编程中经常使用的一个模块,其优点在于当写的代码量比较大的时候方便修改检查,可以做到改一变"百". 一.宏定义 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏 ...

最新文章

  1. java tostringutils_StringUtils
  2. 最先进的AI还不如动物聪明?首届AI-动物奥运会英国开赛!
  3. lampp mysql 等待响应时间很长,XAMPP 最大执行时间(max_execution_time) 问题
  4. 正确的WordPress文件权限[关闭]
  5. Tensorflow 梯度下降实例
  6. 2017蓝桥杯省赛---java---A---2(9数算式)
  7. typescript主键自增长
  8. Windows驱动—64位驱动测试64位驱动测试签名
  9. Python内置GUI模块Tkinter的几点笔记
  10. 简单的商品信息管理系统(Java 和sql server数据库)源码
  11. html5 blockquote,html5 – 正确的HTML Blockquote
  12. 为何要使用加密邮箱?
  13. 软件工程-软件工程基本概念
  14. 黑盒测试、白盒测试、灰盒测试的区别
  15. javaScript小案例------js实现手风琴效果篇
  16. SpringSecurity:授权
  17. 五子棋java百度文库_JAVA课程设计 五子棋(内附完整代码).doc
  18. SQL server 复杂查询
  19. FreeModbus源码结构分析
  20. 5.execve()到底干了啥?

热门文章

  1. 解决城市内涝的措施有哪些?需要用到哪些监测设备?
  2. 百度飞桨小白逆袭大神被“虐”过程大公开--青春有你2 数据分析
  3. 2022-09-26 工作记录--React-js将时间戳转换成“时分秒”+“时分秒”的倒计时(含tab切换)
  4. css 按钮去掉浮雕效果,如何使用css完成以下浮雕效果
  5. 《 Kotlin极简教程 》陈光剑 编著(机械工业出版社,2017.9)
  6. 二极管电路的分析方法
  7. 服装店用什么收银-纳客收银系统
  8. css 首字母,css如何设置英文首字母大写
  9. Windows Media Player播放视频导致程序闪退
  10. 【JavaWeb开发-Servlet】拾起海中的漂流瓶超强版