学习目标:
掌握宏定义
重点:
宏定义编译预处理命令的正确使用
难点:
宏定义
引言:
掌握宏定义、文件包含和条件编译,分别用宏定义命令、文件包含命令和条件编译命令来实现。
为了和一般C语句相区别,这些命令以符号“#”开头。
一、无参宏
1、无参宏的定义格式
#define 标识符 字符串
“define”为宏定义命令。
“标识符”为所定义的宏名,通常用大写字母表示,以便于与变量区别。
“字符串”可以是常数、表达式等。
“宏”: 用一个标识符来表示一个字符串。
“宏名”:被定义为“宏”的标识符。
“宏替换”:在编译预处理时,预处理程序将程序中所有出现的“宏名”,都用宏定义中的字符串去替换。完成后,才将程序交给编译程序去处理。
2、使用宏定义的优点
(1) 可提高源程序的可维护性;
(2) 可提高源程序的可移植性;
(3) 减少源程序中重复书写字符串的工作量。
3、关于宏定义几点说明
(1) 宏名一般用大写字母表示,以示与变量区别。但这并非是语法规定。
(2) 宏定义不是C语句,所以不能在行尾加分号。
(3) 在宏展开时,预处理程序仅按宏定义简单替换宏名,而不作任何检查。
(4) 宏定义命令#define出现在函数的外部,宏名的有效范围是:从定义命令之后,到本文件结束。
(5) 在进行宏定义时,可以引用已定义的宏名。
(6) 对双引号括起来的字符串内的字符,即使与宏名同名,也不进行宏展开。
4、符号常量
在定义无参宏时,如果宏定义中的“字符串”是一个常量,则相应的“宏名”称为符号常量。
二、有参宏
1、有参宏的定义格式
# define 宏名(参数表) 字符串
# define ADD(X,Y) (X+Y)
2、有参宏的调用和宏展开
(1) 调用格式:宏名(实参表)
(2) 宏展开:用宏调用提供的实参字符串,直接替换宏定义命令行中相应形参字符串,非形参字符保持不变。
# define ADD(X,Y) (X+Y)
…
sum = ADD(3,5) ;
宏替换时,用实参3和5 去代替形参X 和Y,经预处理宏展开后的语句为:
sum = (3+5) ;
3、关于有参宏的几点说明
(1) 定义有参宏时,宏名与左圆括号之间不能留有空格。
(2) 有参宏定义中,形参不分配内存单元,因此形参不必做类型定义;而宏替换中的实参有具体的值,要用它们去代换形参,因此实参必须做类型说明。在有参宏中,只是符号替换。
(3) 调用有参宏名时,一对圆括号必不可少,圆括号中实参的个数应该与形参个数相同,如果有多个参数,参数之间用逗号隔开。
(4) 在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。宏替换时对实参表达式不做计算直接照原样替换。
(5) 在宏定义中,字符串内的形参和整个表达式通常要用括号括起来以避免出错。
三、应用举例
1.例10.1:阅读以下程序,观察程序结果。
2.例10.2:阅读以下程序,观察程序结果。
3.例10.3:阅读以下程序,观察程序结果。
4.例10.4:阅读以下程序,观察程序结果。
5.例10.5:阅读以下程序,观察程序结果。
6.例10.6:阅读以下程序,观察程序结果。
7.例10.7:阅读以下程序,观察程序结果。
讨论题:
1)例10.1中的“#define PI 3.14159”就是宏定义,它的作用是什么呢?
2)例10.7和例10.6稍有不同,在宏定义中将整体字符串及形参加了括号,调用就发生了什么变化?

