8.1.1 不带参数的宏定义

不带参数的宏定义是用来做什么的呢?用一句话描述:用一个指定的宏名来代表一串内容。宏名,其实就是一个标识符。其一般形式为:

作用:用PI来代替3.1415926,那么在程序源码中写的是PI(也就是上述一般形式中的宏名),在预处理阶段,所有在该#define语句行之后的代码中出现的PI都会被替换成3.1415926。有几点说明:

(1)#define就是宏定义命令,实现了用一个简单的名字(宏名)代替一个很长内容的效果,在预编译时将宏名替换成指定内容的过程称为“宏展开”,也可以称为“宏替换”,上面用PI替换成3.1415926的过程就是宏展开。

(2)利用#define,增加了代码修改的方便性,为代码修改提供极大便利,这种能力在开发中被频繁地使用。例如,如果将来PI不等于3.1415926,而是等于2.58了,那么只需要修改一行代码,整个程序中出现PI的地方就都被替换成了2.58,这也叫作提高了程序的可移植性。看看如下范例:

针对上面的代码,在进行宏展开时,PI会被直接替换成3.1415926,并不做语法检查,所以替换完后直接参与乘法运算,即“ftmp=2*PI;”相当于“ftmp=2*3.1415926;”。有几点说明:

①宏名一般用大写字母表示,这是一种习惯,建议遵照这个习惯。

②宏定义其实并不是C语言语句(虽然有时候会称其为语句),不必在行末加分号,如果加分号则连分号一起被替换了,看如下代码:

③#define命令出现在程序中函数的外面,宏名的有效范围是#define之后到本源程序文件结束,不能跨文件使用,如果在另外一个源程序文件中使用,则需要在另外一个源程序文件中也做相同定义,或者把这些#define定义统一放到一个公共文件(如.h头文件)里,并用8.2节要讲解的#include(以往也简单介绍和使用过)把这个公共文件包含到每个源程序文件中去。一般来说,#define命令都写在源程序文件开头部分,函数之前。

④可以用#undef命令终止宏定义的作用域,不过#undef命令用得比较少。看看如下范例:

⑤用#define进行宏定义时,还可以引用已定义的宏,可以层层置换。看看如下范例:

宏展开之后:

DPI被替换成2*3.1415926,DPICPI被替换成3.1415926*2*3.1415926。

⑥字符串内的字符即便与宏名相同,也不进行替换。看看如下范例: