C语言#define用法总结

发布时间:2018-06-06 16:27:54

C语言#define用法总结

黄海涛,2012-3-3

如果你还在为使用#define而迷茫,那请阅读这篇文章;

如果读完之后你还在迷茫,那请哪天心情好了,再回来读一遍。:)

欢迎跟着我的思路走……

一、 概述

1、 宏定义

C语言中,以#开头的为预处理命令。

定义形式:

#define name replacement text

2、 本质

其本质是:使用宏定义中的字符串替换(Substitution)宏名。

这只是一种简单的代换,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。

3、 替换时机

预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。由预处理程序负责完成。在源程序被编译之前,宏替换已经完成,其流程如下:

源程序 预处理程序 预处理后的源程序 编译器

4、 作用域

其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用# undef命令。

5、 优缺点

▲优点:宏定义使用得当,可以防止出错,提高可移植性,可读性等等;减少函数调用的开销。

▲缺点:可能存在参数副作用;展开后可能比函数调用开销更大。

※规则一:保证在宏替换之后不会发生错误。

二、 无参宏定义

1、 定义的一般形式

#define identifier token-sequence

#define 标识符 字符串

2、 简单常量

代替有实际意义的常量,如:

约束1:宏名通常采用易读大写字母表示。

约束2:宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起替换。

约束3:宏名在源程序中若用引号引起来,则预处理程序不对其作宏替换。如:

3、 字符串为表达式

※规则无参宏定义中字符串为表达式(即含有运算符),必须加小括号()

可见,有括号与无括号差别很大,请小心加括号,保证展开后是你所期望的。参考规则一。

4、 嵌套使用

5、 指明数据类型限制

6、实例

三、 带参宏定义

对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

1、 带参宏定义的一般形式为:

#define identifier(identifier-list) token-sequence

#define 宏名(形参表) 字符串

在字符串中含有各个形参,形参是标识符。

带参宏调用的一般形式为:

宏名(实参表)

约束4:带参宏定义中,宏名和‘(’之间不能有空格出现。

※规则带参宏定义中,字符串是表达式(不是语句),要求严格加小括号,即对每个参数、每一层运算、整个字符串都要求加小括号。

2、 简单用法:

我们经常讨论的一个宏定义:给定两个整数,求其中较大者。有很多人无法将它完全写正确。

看到了吧,编写一条正确的宏定义不容易,如果你不按规则办事,总有一天你会为调试它而费上九牛二虎之力!(而且你是没有办法在宏定义处设置断点的,因为在编译之前,宏展开已完成。)

3、 占用多行的写法

可以用\换行续写

4、 字符串为语句

规则字符串为语句,要求加大括号。

如下调用:

加大括号后的问题:

如下调用:

如果你非得用宏定义来写的话,那就得如下处理:

四、 特殊用法

1、 防止头文件被重复包含

2、 表示数据类型(更多的时候是使用typedef

因为宏并不是类型定义,只是简单替换而已。

3、 连接

4、 添加单引号

5、 添加双引号

以上三个特殊运算符(##, #@#),会影响替换过程。

1) 它们后面紧接形式参数的话,将会进行相应的操作(连接或加引号)

2) 当宏展开后,再次扫描并再次遇到此类标识符时不再执行替换,而是保持不变。

3) 当宏展开后,得到的最终结果以#开头,不会认为是预处理命令。

五、 宏定义中的问题

1、 参数可能有副作用

解决办法:

1) 确保参数没有副作用;

2) 将宏改写为函数,进行函数调用;

3) 直接写运算代码。

2、 导致效率低下

解决办法:

1) 直接写运算代码;

2) 将宏改写为函数,进行函数调用。

有了对基本用法的掌握,分析相对复杂一些的情况应该不在话下了。另外,文中肯定存在很多不足之处,恳请阅读者批评指正,相互交流,学习提高。

六、 参考资料

1C程序设计》(第三版):谭浩强著,清华大学出版社2005.07

2、《C程序设计语言(The C Programming Language)(2文版)()Brian W.KernighanDennis M.Ritchie著,徐宝文 李志译,机械工业出版社2004 1

3、《C专家编程(Expert C Programming)(文版)()林登(LinDenP.V.D)著徐波译人民邮电出版社2002.12

4、《C陷阱与缺陷(C Traps And Pitfalls)(文版)()Andrew Koenig高巍人民邮电出版社2003

5、《C语言深度解剖陈正冲著,北京航空航天大学出版社2010

6、《想成为嵌入式程序员应知道的0x10个基本问题.doc作者Jones Nigel

C语言#define用法总结

相关推荐