第12章 编译预处理..ppt

* 第12章 编译预处理   每个C编译系统都提供了一组预处理命令。编译预处理命令都是以“#”开头,它不是C语句,必须单独占一行,末尾不使用分号作为结束符。   在C的源程序被编译以前,首先对源程序中的预处理命令进行处理,然后才对程序进行编译。预处理命令可以出现在源程序的任何地方,但一般放在源程序的开头,作用域是从当前所放置的地方开始到文件结束,超出文件就失去作用。 12.1 宏定义   在C源程序中,允许用一个标识符来表示一个字符串,称为“宏”,宏是一种编译预处理命令。被定义为“宏”的标识符称为“宏名”。   在编译预处理时,对程序中所有出现的“宏名”都用宏定义中的字符串去替换,这称为“宏替换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏替换是由预处理程序自动完成的。 12.1.1无参宏定义 1. 无参宏定义命令的语法格式  无参宏定义命令的一般格式如下:   #define 标识符 字符串  其中,“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。#define命令出现在程序中所有函数的外面,宏名的有效范围为定义命令之后到本源文件结束,但可用#undef命令终止宏定义的作用域。 在前面介绍过的符号常量的定义就是一种无参宏定义。 例如,以下命令定义宏名PI代表圆周率3.14159:   #define PI 3.14159 2. 说明  (1)根据一般C程序中变量的命名规则,符号常量的定义一般习惯使用大写字母表示,这主要是因为通常在一般变量的定义中,常使用小写字母的原因。当然,符号常量也可以小写字母命名。  (2)宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,属于一种简单的代换。其中,所表示的字符串可含任意字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开的源程序的过程中发现问题。  (3)宏定义常用于程序中反复使用的表达式。  (4)当宏定义在一行中写不下,需要在下一行继续时,只需在最后一个字符后紧接着加一个反斜线“\”。例如:   #define LEAP_YEAR year%4==0 \     year%100!=0 || year%400==0  (5)宏定义不是语句,在行末不必加分号,如加上分号则连分号也一起置换。例如,以下程序没有语法错误,能正确运行,执行结果为4:   #include stdio.h   #define X 2;   void main()   {  int y;     y=2*X /*其后没有逗号,但宏展开为:y=2*2;是正确的语句*/ printf(%d\n,y); }  (6)宏名在源程序中若用引号括起来,则预处理程序不对其作宏替换。例如:   #include stdio.h   #define STR this is a string   void main()   { printf(STR=%s\n,STR);   }   在括号内的STR不展开,只展开第二个str。输出为:   STR=this is a string  (7)宏定义允许嵌套,即在宏定义的字符串中可以使用已经定义的宏名,并且在宏展开时由预处理程序层层代换。例如:   #define X 2+3   #define Y X*X  在程序设计中,如有语句:   printf(%d\n,Y);  则在宏替换后变为:   printf(%s\n,2+3*2+3); 结果输出11。  (8)宏定义是预处理指令,与定义变量不同,它只是进行简单的字符串替换,不分配内存。 12.1.2 带参宏定义  C允许宏带有参数。在宏定义中的参数称为形式参数,简称为形参,在宏调用中的参数称为实际参数,简称为实参。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。 1. 带参宏定义命令的语法格式  带参宏定义命令的一般格式如下:    #define 标识符(形参表) 字符串  其中,括号中的“形参表”是由一个或多个形参组成的,当有一个以上的形参时,形参之间用逗号分隔。对带参宏的展开也是用字符串代替宏名,但是其中的形参要用相应的实参代替。 2. 带参宏调用的语法格式  带参宏调用的一般格式如下:   宏名(实参表)  例如:   #define M(x,y) x*x+y*y   ┇   y=M(2,4);   ┇   在宏调用时,用实参2代替形参x,4代替形参y,经预处理宏展开后的语句为:   y=2*2+4*4; 3. 说明  (1)带参宏定义中,宏名和形参表之间不能有空格出现。例如:    #define MAX(a,b) (ab)?a:b  /*正确形式*/  写为:   

文档评论(0)

1亿VIP精品文档

相关文档