C程序设计第9章编译预处理.docVIP

  • 12
  • 0
  • 约 7页
  • 2016-06-27 发布于重庆
  • 举报
C程序设计第9章编译预处理

第9章 编译预处理 9.1宏定义 宏定义的作用是用标识符来代表一个字符串,即给字符串取名。C语言中用#define开头的命令对一字符串命名,这就是宏定义。C编译系统在编译之前将这些标识符替换成所定义的这串字符。因此宏定义命令属于编译预处理命令。 宏定义分不带参数的宏定义和带参数的宏定义。 9.1.1不带参数的宏定义 不带参数的宏定义的一般格式为: #define 标识符 字符串 标识符称为这串字符的宏名,在程序中用宏名替代字符串称为宏调用。预编译时将字符串替换宏名的过程称为宏展开。 例如:#define PI 3.1415926 这里的PI就是宏名,它代表字符串3.1415926,预编译时将源程序中所有宏名PI出现的位置用字符串3.1415926来替换。 说明: ⑴ 宏名一般用大写字母表示,以便与普通变量相区别。 ⑵ #与define间一般不留空格,宏名两侧必须至少用一个(可以多个)空格分隔。 ⑶ 宏定义字符串后不能以分号结尾,否则分号将作为字符串的一部分参加宏展开,造成编译时出错。 例如,某程序中有宏定义 #define PI 3.1415926; 程序中调用宏定义的语句 a=PI*r*r; 在编译预处理时,将宏展开成: a=3.1415926;*r*r; ↑分号将作为字符串的一部分参加宏展开 这显然是错误的,编译时会出错。 ⑷ 宏定义用宏名代替一个字符串,并不管它的数据类型是什么,也不管词法和语法是否正确,只作简单的替换。 例如: #define PI 3.14I5926 即在宏定义时将数字1误写成字母I,预处理时照样代入,只有在编译时经宏展开后的源程序时才会发现错误。 ⑸ #define命令定义的宏名作用范围是从定义命令开始直到源程序文件结束,一般情况下,#define总是定义在文件开头,函数之间。还可以在程序中通过#undef终止宏名的作用域。 #define E 2.71828 main( ) { E的有效范围 . . . } #undef E fun( ) { . . . } 由于#undef的作用,使E的使用范围在#undef处结束,因此函数fun中,E不再表示2.71828,这样可以灵活控制宏定义作用范围。 ⑹ 宏定义中,可以出现已定义的宏名,还可以层层置换。 ⑺ 若宏名出现在一个被双引号括起来的字符串中时,将不会产生宏替换。 #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R main() { printf(L=%7.2f\nS=%7.2f\n,L,S); } 运行结果 L=18.85 S=28.27 程序分析 经过宏展开后,printf函数中的输出项L被展开成2*3.1415926*3.0,S展开成3.1415926*3.0*3.0,双引号内的L,S不作替换。 ⑻ 宏定义是专用于预处理的一个名词,它与定义变量含义不同,只用字符简单替换,不分配内存空间。 9.1.2带参数的宏定义 带参数的宏定义不是进行简单的字符串替换,还要进行参数替换,带参数的宏定义一般形式为 #define 宏名(参数表) 字符串 例如,#define S(a,b) a*b area=S(3,2); 这里S为宏名,a和b为形式参数;程序中调用S(3,2)时,把实参3与2分别代替形参a与b,因此,赋值语句宏展开为 area=3*2; 对带参的宏定义展开规则如下:在程序中如果有带实参的宏(如S(3,2)),则按#define命令行中指定的字符串从左到右进行置转,如果串中包含宏中的形参(如a,b),则将程序语句中相应的实参(可以是常量、变量或表达式)代替形参,其它字符则原样保留,这样就形成了替换后的字符串。如图9-1所示。 #define S(a,b) a*b area=S(3,2); 得 3*2 图9-1 带参数的宏定义展开 【例9-2】用带参数的宏定义求两数中的大数并输出。 #define MAX(a,b) (ab)?a:b main() {int i,j; i=15; j=20; printf(MAX=%d\n,MAX(i,j)); } 运行结果 MAX=20 程序分析:该程序在编译前,表达式MAX(i,j)被定义的字符串所替换,其中的i和j作为实参替换字符串中对应的形参a和b,其它符号不变。printf

文档评论(0)

1亿VIP精品文档

相关文档