内容正文:
第6章 编译预处理
预处理:是指在进行编译之前所作的工作。
预处理由预处理程序负责完成。当对一个源文件进行编译时, 编译系统将自动引用预处理程序对源程序中的预处理命令作处理, 处理完毕后自动进入对源程序的编译。
1
在前面各章中,已多次使用过以“#”号开头的预处理命令。如包含命令# include,宏定义命令# define等。在源程序中这些命令都放在函数之外, 而且一般都放在源文件的前面,它们称为预处理部分。
预处理命令:#define,#undef,#include,#else,#error……
预处理命令行可位于程序中任意位置
预处理命令行的作用域:定义位置开始到文件结尾
6.1 宏定义:#define
6.2 文件包含:#include
第6章 编译预处理
宏定义是由源程序中的宏定义命令完成的。
在C语言中,“宏”分为有参数宏和无参宏两种。
6.1 宏定义: #define
如:无参宏
#define PI 3.1415926
如:有参宏
# define AS(x,y,z) x+y+z
无参宏定义
一般形式: #define 宏名 宏体
define:宏定义命令
宏名:由标识符定义
宏体:为一字符串(常量、表达式、格式串等)
define、宏名、宏体之间用空格隔开
宏调用格式:宏名
宏替换:编译预处理时进行宏展开,对宏定义命令行后出现的宏名用宏体代替。
4
“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“
#define PI 3.1415926
main()
{float a,s,r;
printf("Input radius r:");
scanf("%f", &r);
a=2*PI*r;
s=PI*r*r;
printf("r=%10.4f
a=%10.4f
s=%10.4f
",r,a,s);
}
宏替换后:
a=2*3.1415926*r;
s=3.1415926*r*r;
实 例
宏调用
宏替换时只是简单地以宏体取代宏名,预处理程序并不作语法检查。如有错误,只能在编译时发现。
#define PI 3.141593;
……
L=2*PI*r;
宏展开后,该语句为:L=2*3.141593;*r;
宏名在源程序中若用引号引起来,则预处理程序不对其作宏代换。如:#define no 220
main()
{ printf(“no”); }
说 明
出错
不替换
宏定义可以嵌套:
在宏体中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。
以下程序中的for循环执行的次数是( )。
#define N 2
#define M N+1
#define NUM 2*M+1
main()
{ int i;
for(i=1;i<=NUM;i++)printf(“%d
”,i); }
A. 5 B. 6 C. 7 D. 8
说 明
思考
#define M y*y+3*y
main(){
int s,y;
printf("input a number: ");
scanf("%d",&y);
s=3*M +4*M +5*M;
printf("s=%d
",s);
}
y*y+3*y
y*y+3*y
y*y+3*y
(y*y+3*y)
(y*y+3*y)
(y*y+3*y)
继续理解
8
去掉括号会怎样
带参宏定义
一般形式: #define 宏名(形参表) 宏体
宏调用:宏名(实参表)
宏替换:编译预处理时用宏体代换带参宏,同时用实参代换形参
例如: # define AS(x,y,z) x+y+z
……
sum=AS(3,4,5);
宏替换后:sum=3+4+5;
9
C语言允许宏带有参数。在宏定义中的参数称为形式参数, 在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开, 而且要用实参去代换形参。
宏定义时,在宏名与带参数的括号之间不能有空格,否则将空格以后的字符都作为宏体.
例如: #define s (r) PI*r*r
下列程序执行后的输出结果是( )。
#define MA(x) x*(x-1)
main()
{ int a=1,b=2;
pr