欢迎来到天天文库
浏览记录
ID:43082061
大小:121.50 KB
页数:27页
时间:2019-09-29
《C语言程序设计教程 第12章 编译预处理》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、第12章编译预处理12.1了解编译预处理12.2宏定义12.3文件包含12.4条件编译12.1了解编译预处理C语言所提供的“编译预处理”功能是它区别于其他高级语言的又一重要特征,其主要功能包括三种:宏定义、文件包含和条件编译,分别由三种命令来实现。为了区别于C语句,预处理命令必须出现在一行的开始并以“#”号打头。12.2宏定义宏定义由#define命令实现,根据实际应用的需要可以分为不带参数的宏定义和带有参数的宏定义两种命令形式。12.2.1不带参数的宏定义命令的一般形式为:#define标识符字符
2、串定义中的“标识符”称为“宏名”。这一命令的作用仅仅是表明用指定的宏名来代替一个指定的字符串。例如:#definePI3.1415926它的作用是指定用宏名PI来代替“3.1415926”这个字符串。在预编译时,程序中所有出现“宏名”的地方,都将由这个字符串的内容进行替换,此过程称为“宏展开”。说明(1)不带参数的宏定义常常被用于定义符号常量。这样既可以提高程序的通用性,也便于修改。例12.1用宏名限定数组的大小。#defineN10/*定义宏名N*/voidArrIn(inta[]){inti;f
3、or(i=0;i4、592bmain(){floats,r=2.5;s=PI*r*r;printf("s=%f",s);}程序中在定义代表值的宏名PI时,将字符串3.1415926中的数字6误写作了字母b。这一宏定义命令本身并不构成错误。因为宏名PI代表的是字符串“3.141592b”,而不是数值。但在程序中引用了宏名PI来计算圆面积,赋值语句:s=PI*r*r;经宏展开后变为:s=3.141592b*r*r;从而导致编译出错。虽然出错位置在此赋值语句,但引发这一错误的根源还是上述宏定义命令。(3)宏展开时,不对5、双引号括起来的字符串中的内容进行替换。如有定义:#definePI3.14159语句:printf("PI=%f",PI);中有2个PI,第一个PI是在双引号内的,它不被替换;第二个PI在双引号外,它将被展开成3.14159。(4)在#define命令行中可以没有“字符串”,即表示成:#define标识符如:#defineDEBUG这里仅仅是为了表明标识符DEBUG已经“被定义”。这种定义形式在条件编译中将会用到。(5)为了与变量名相区别,一般习惯用大写字母作宏名。但这不是规定,只是约定俗成。16、2.2.2带参数的宏定义1.定义形式#define宏名(形参表)字符串例如:#defineCYC(r)2*3.14159*r说明(1)这里定义了一个计算圆周长的宏CYC(r),宏名CYC与其后的左括号之间不得留有空格,否则CYC将被视为不带参数的宏。(2)作为替换文本的字符串中应含有括号中的参数,如2*3.14159*r中的r。否则,就没有必要定义带参数的宏。(3)字符串中可以包含已经定义过的宏名。例如:#defineCR""#defineD"%d"#definePRIDCR则语句:printf7、(PRI,20);执行后的输出结果为:20。2.宏展开的过程程序中若调用了带参数的宏,预编译时不仅仅是进行简单的字符串替换,还涉及到参数的替换。宏展开的过程是:按命令行中指定的字符串从左到右进行置换,遇到形参则以实参代替,对于非参数字符则原样保留。若有语句:x=CYC(2.5);宏展开时将用实参2.5替换字符串“2*3.14159*r”中的形参r,其他字符不变。置换后的语句为:x=2*3.14159*2.5;说明(1)由于宏定义是在预编译时展开的,它不具有任何计算功能。宏展开时,若实参是一个表达式,8、也是原样置换,而不进行求值。如有语句:y=CYC(3+5);这里用实参3+5替换“2*3.14159*r”中的形参r后得到:y=2*3.14159*3+5;而不是:y=2*3.14159*8;/*3和5不能先做加法运算*/(2)显然,为确保宏调用的正确性,在定义宏时,应将字符串中的形参用括号括起来。例如:#defineCYC(r)2*3.14159*(r)这时将语句y=CYC(3+5);展开后为:y=2*3.14159*(3+5);有时还需要在整个字符串外面加括号。如
4、592bmain(){floats,r=2.5;s=PI*r*r;printf("s=%f",s);}程序中在定义代表值的宏名PI时,将字符串3.1415926中的数字6误写作了字母b。这一宏定义命令本身并不构成错误。因为宏名PI代表的是字符串“3.141592b”,而不是数值。但在程序中引用了宏名PI来计算圆面积,赋值语句:s=PI*r*r;经宏展开后变为:s=3.141592b*r*r;从而导致编译出错。虽然出错位置在此赋值语句,但引发这一错误的根源还是上述宏定义命令。(3)宏展开时,不对
5、双引号括起来的字符串中的内容进行替换。如有定义:#definePI3.14159语句:printf("PI=%f",PI);中有2个PI,第一个PI是在双引号内的,它不被替换;第二个PI在双引号外,它将被展开成3.14159。(4)在#define命令行中可以没有“字符串”,即表示成:#define标识符如:#defineDEBUG这里仅仅是为了表明标识符DEBUG已经“被定义”。这种定义形式在条件编译中将会用到。(5)为了与变量名相区别,一般习惯用大写字母作宏名。但这不是规定,只是约定俗成。1
6、2.2.2带参数的宏定义1.定义形式#define宏名(形参表)字符串例如:#defineCYC(r)2*3.14159*r说明(1)这里定义了一个计算圆周长的宏CYC(r),宏名CYC与其后的左括号之间不得留有空格,否则CYC将被视为不带参数的宏。(2)作为替换文本的字符串中应含有括号中的参数,如2*3.14159*r中的r。否则,就没有必要定义带参数的宏。(3)字符串中可以包含已经定义过的宏名。例如:#defineCR""#defineD"%d"#definePRIDCR则语句:printf
7、(PRI,20);执行后的输出结果为:20。2.宏展开的过程程序中若调用了带参数的宏,预编译时不仅仅是进行简单的字符串替换,还涉及到参数的替换。宏展开的过程是:按命令行中指定的字符串从左到右进行置换,遇到形参则以实参代替,对于非参数字符则原样保留。若有语句:x=CYC(2.5);宏展开时将用实参2.5替换字符串“2*3.14159*r”中的形参r,其他字符不变。置换后的语句为:x=2*3.14159*2.5;说明(1)由于宏定义是在预编译时展开的,它不具有任何计算功能。宏展开时,若实参是一个表达式,
8、也是原样置换,而不进行求值。如有语句:y=CYC(3+5);这里用实参3+5替换“2*3.14159*r”中的形参r后得到:y=2*3.14159*3+5;而不是:y=2*3.14159*8;/*3和5不能先做加法运算*/(2)显然,为确保宏调用的正确性,在定义宏时,应将字符串中的形参用括号括起来。例如:#defineCYC(r)2*3.14159*(r)这时将语句y=CYC(3+5);展开后为:y=2*3.14159*(3+5);有时还需要在整个字符串外面加括号。如
此文档下载收益归作者所有