第九章 编译预处理
- 格式:doc
- 大小:36.50 KB
- 文档页数:5
第九章 编译预处理编译指令(编译预处理指令):C 源程序除了包含程序命令(语句)外,还可以使用各种编译指令(编译预处理指令)。
编译指令(编译预处理指令)是给编译器的工作指令。
这些编译指令通知编译器在编译工作开始之前对源程序进行某些处理。
编译指令都是用“#”引导。
编译预处理:编译前根据编译预处理指令对源程序的一些处理工作。
C 语言编译预处理主要包括宏定义、文件包含、条件编译。
编译工作实际分为两个阶段:编译预处理、编译。
广义的编译工作还包括连接。
9、1 宏定义宏定义:用标识符来代表一个字符串(给字符串取个名字)。
C 语言用“#define ”进行宏定义。
C 编译系统在编译前将这些标识符替换成所定义的字符串。
宏定义分为不带参数的宏定义和带参数宏定义。
9、1、1 不带参数宏定义(简单替换)1其中:标识符-宏名。
2、宏调用:在程序中用宏名替代字符串。
3、宏展开:编译预处理时将字符串替换宏名的过程,称为宏展开。
说明:(1)宏名遵循标识符规定,习惯用大写字母表示,以便区别普通的变量。
(2)#define之间不留空格,宏名两侧空格(至少一个)分隔。
(3)宏定义字符串不要以分号结束,否则分号也作为字符串的一部分参加展开。
从这点上看宏展开实际上是简单的替换。
例如:#define PI 3.14; 展开为s=3.14;*r*r ;(导致编译错误)(4)宏定义用宏名代替一个字符串,并不管它的数据类型是什么,也不管宏展开后的词法和语法的正确性,只是简单的替换。
是否正确,编译时由编译器判断。
例如:#define PI 3.I4 照样进行宏展开(替换),是否正确,由编译器来判断。
(5)#define 宏定义宏名的作用范围从定义命令开始直到本源程序文件结束。
可以通过#undef 终止宏名的作用域。
(6)宏定义中,可以出现已经定义的宏名,还可以层层置换。
(7)宏名出现在双引号“”括起来的字符串中时,将不会产生宏替换。
(因为出现在字符串中的任何字符都作为字符串的组成部分)(8)宏定义是预处理指令,与定义变量不同,它只是进行简单的字符串替换,不分配内存。
第9章编译预处理本章要求:1、熟悉宏定义与宏扩展。
a宏与函数的区别。
2、熟悉文件包含命令#include的作用及其预处理方法。
3、熟悉条件编译的使用。
概述编译预处理:在源程序文件中,加入“编译预处理命令”,使编译程序在对源程序进行通常的编译(包括词法分析、语法分析、代码生成、代码优化)之前,先对这些命令进行预处理,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码(OBJ文件)。
C提供的编译预处理命令:宏命令(Macro)、文件包含命令(include)、条件编译命令这些命令均以#开头,以区别于语句。
9.1 宏定义(Macro)一、不带参数的宏一般形式: #define 标识符字符串如: #define PI 3.1415926作用:用标识符(称为“宏名”)PI代替字符串“3.1415926”。
在预编译时,将源程序中出现的宏名PI替换为字符串“3.1415926”,这一替换过程称为“宏展开”。
#define:宏定义命令#undef:终止宏定义命令[例9.1]#define PI 3.1415926main(){ float l,s,r,v;printf("input radius:");scanf("%f",&r); /* 输入圆的半径*/l = 2.0*PI*r; /* 圆周长*/s = PI*r*r; /* 圆面积*/v = 4.0/3.0*PI*r*r*r; /* 球体积*/printf("l=%10.4f\ns=%10.4f\nv=%10.4f\n",l,s,v);}关于宏定义的说明:1、一般宏名用大写字母表示。
(变量名一般用小写字母)。
2、使用宏可以提高程序的可读性和可移植性。
如上述程序中,多处需要使用π值,用宏名既便于修改又意义明确。
3、宏定义是用宏名代替字符串,宏扩展时仅作简单替换,不检查语法。
语法检查在编译时进行。
第九章编译预处理
一、单选题
1.以下对宏替换的叙述不正确的是
A)宏替换只是字符的替换B)宏替换不占运行时间
C)宏名无类型,其参数也无类型
D)带参的宏替换在替换时,先求出实参表达式的值,然后代入形参运算求值2.宏定义#define PI 3.14中的宏名PI代替
A)一个单精度实数)B)一个双精度实数
C)一个字符串 D)不确定类型的数
3.有以下宏定义
#define k 2
#define X(k) ((k+1)*k)
当C程序中的语句y = 2 * (K + X(5));被执行后,
A)y中的值不确定 B)y中的值为65
C)语句报错 D)y中的值为34
4.以下程序的输出结果是
#define MIN(x, y) (x) < (y) ? (x) : (y)
main()
{ int i , j, k;
i = 10; j = 15;
k = 10 * MIN(i, j);
printf(“%d\n”, k);
}
A)15 B)100 C)10 D)150
5.以下程序中的for循环执行的次数是
#define N 2
#define M N + 1
#define NUM (M + 1) * M / 2
main()
{ int i;
for(i = 1; i <= NUM; i++);
pritnf(“%d\n”, i );
}
A)5 B)6 C)8 D)9
6.以下程序的输出结果是
#include “stdio.h”
#define FUDGF(y) 2.84 + y
#define PR(a) printf(“%d”, (int) ( a ) ) #define PRINT1(a) PR(a); putchar(‘\n’)
main()
{ int x = 2;
PRINTF1(FUDGF(5) * X);
}
A)11 B)12 C)13 D)15
7.以下程序的输出结果是
#define FMT “%d,”
main()
{
int b[][4] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23};
printf(FMT, *(*(b+1)+1));
printfFMT, b[2][2]);
}
A)1,11, B)1,11 C)11,21, D)13,21
8.若有宏定义如下:
#define MOD(x,y) x%y
则执行以下程序段的输出为
int z, a = 15, b = 100;
z = MOD(b, a);
printf(“%d\n”, z++);
A)11 B)10 C)6 D)5
二、填空题
1.有以下宏定义和赋值语句,宏置换后的赋值语句的形式是。
#define A 3+5
……
p = A * A;
2.以下程序的输出结果是。
#define PR(ar) printf(“ar = %d“, ar)
main()
{ int j, a[] = { 1, 3, 5, 7, 9, 11, 13, 15}, *p = a + 5;
for(j = 3; j ; j--)
switch( j )
{ case 1:
case 2: PR(*p++); break;
case 3: PR(*(--p) );
}
}
3.以下程序的执行结果是。
#define DOUBLE(r) r*r
main()
{
int y1 = 1, y2 = 1, t;
t = DOUBLE(y1 + y2);
printf(“%d\n”, t);
}
4.以下程序的执行结果是。
#define PRINT(V) printf(“V = %d\t”,V)
main()
{
int a, b;
a = 1;
b = 2;
PRINT(a);
PRINT(b);
}
第九章编译预处理
一、选择题
1.【A】【B】【C】【D】 2.【A】【B】【C】【D】 3.【A】【B】【C】【D】4.【A】【B】【C】【D】 5.【A】【B】【C】【D】 6.【A】【B】【C】【D】7.【A】【B】【C】【D】 8.【A】【B】【C】【D】
二、填空题
1. p = 3+5*3+5;
2. ar = 9 ar = 9 ar = 11
3. 3
4. V = 1 V = 2。