目录
主要讲解了预处理的三种方式,分别是宏定义、文件包含和条件编译。其中,宏定义是最常用的一种预处理方式,文件包含对于程序功能的扩充很有作用,条件编译可以优化程序代码,熟练掌握这三种预处理方式,对于以后的程序设计至关重要。
一、宏定义
1.1 不带参数的宏定义
在程序中,经常会定义一些常量,比如,3.14、“ABC”。如果这些常量在程序中被频繁使用,难免会出现书写错误的情况。为了避免程序书写错误,可以使用不带参数的宏定义来表示这些常量,其语法格式如下所示:
#define 标识符 字符串
在上述语法格式中,“#define”用于标识一个宏定义,“标识符”指的是所定义的宏名,“字符串”指的是宏体,它可以是常量、表达式等。一般情况下,宏定义需要放在源程序的开头,函数定义的外面,它的有效范围是从宏定义语句开始至源文件结束。
下面看一个具体的宏定义,示例代码如下:
#define PI 3.141592
在上述宏定义的作用就是使用标识符PI来代表值3.141592。如此一来,凡随后源代码中出现PI的地方都会被替换为3.141592。接下来通过一个案例来验证
1 #include <stdio.h>
2 #define PI 3.141592
3 void main()
4 {
5 printf("%f\n", PI);
6 }
首先定义了一个宏PI,值为3.141592,然后在main()函数内,使用printf()语句输出了PI的值。从图8-1中可以看出,程序输出的PI的值为3.141592,宏定义起作用了。
注意:
1、如果宏定义中的字符串出现运算符,需要在合适的位置加上括号,例如:
#define S 3+4
如果有一个语句a=S*c;宏定义替换后的语句是a=3+4*c,这样的运行结果显然不符合需求。
2、宏定义的末尾不用加分号,如果加了分号,将被视为被替换的字符串的一部分。由于宏定义只是简单的字符替换,并不进行语法检查,因此,宏替换的错误要等到系统编译时才能被发现。例如:
#define Max=20;
……
if(result==Max)
break;
经过宏定义替换后,其中的if语句将变为:
if(result==20;)
显然上述语句存在语法错误。
除了#define之外,相应地还有#undef指令,#undef指令用于取消宏定义。在#define定义了一个宏之后,如果预处理器在接下来的源代码中看到了#undef指令,那么#undef后面这个宏就都不存在了
1.2 带参数的宏定义
通过1.1小节的学习,发现不带参数的宏定义只能完成一些简单的替换操作。如果希望程序在完成替换过程中,能够进行一些更加灵活的操作,比如,根据不同的半径计算圆的面积,这时可以使用带参数的宏定义,其语法格式如下所示:
#define 标识符(形参表) 字符串
在上述语法格式和不带参数的宏定义有些类似,不同的是多了一个括号,括号中的“形参表”由一个或多个形参组成,当多于一个形参时,形参之间要用逗号进行分隔。对于带参数的宏定义来说,同样需要使用字符串替换宏名,使用实参替换形参。
1 #include <stdio.h>
2 #define PI 3.14
3 #define COMP_CIR(x) 2 * PI * x
4 void main()
5 {
6 double r = 1.0;
7 printf("2 * pi * r = %f\n", COMP_CIR(r));
8 }
第2行和第3行分别定义了一个宏定义,其中,第3行是一个带参数的