ImageVerifierCode 换一换
格式:DOCX , 页数:25 ,大小:27.40KB ,
资源ID:24692464      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/24692464.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(c语言基础教程第六章预处理功能和类型定义.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

c语言基础教程第六章预处理功能和类型定义.docx

1、c语言基础教程第六章预处理功能和类型定义第六章预处理功能和类型定义6. 1 预处理功能概述 本节主要讲述预处理功能的特点。 预处理功能是由很多预处理命令组成,这些命令将在编译时进行通常的编译功能包含词法和语法分析、代码生成、优化等之前进行处理,故称为预处理.预处理后的结果和源程序一起再进行通常的编译操作,进而得到目标代码。 预处理功能主要包括如下三种;宏定义、文件包含和条件编译。 这些功能是通过相应的宏定义命令、文件包含命令和条件编译命令来实现。这些命令不同于C语言的语句,因为它们具有如下的特点: (1)多数预处理命令只是一种替代的功能,这种替代是简单的替换,而不进行语法检查。 (2)预处理命

2、令都是在通常的编译之前进行的,编译时已经执行完了预处理命令,即对预处理后的结果进行编译,这时进行词法和语法分析等通常的程序编译。 (3)预处理命令后面不加分号,这也是在形式_七与语句的区别。 (4)为了使预处理命令与一般C语言语句相区别,凡是预处理命令都以井号(#)开头。 (5)多数预处理命令根据它的功能而被放在文件开头为宜,但是根据需要,也可以放到文件的其他位置。不要产生错觉,好像所有的预处理命令都必须放在文件开头。 学习和掌握预处理功能时,应该了解它的上述规定,以便正确地使用和理解这些预处理命令。6.2.1 简单宏定义1.简单宏定义的格式和功能 简单宏定义的格式如下: #define标识符

3、)(字符串 其中,define是关键字,它表示该命令为宏定义,悦标识符)是宏名,它的写法同标识符。用来表示所代表的字符串。 简单宏定义是定义一个标识符(宏名)来代表一个字符串。 前面讲过的符号常量就是用这种简单宏定义来实现的。例如: #define PI 3.14159265 这是一条宏定义的命令,它的作用是用指定的标识符PI来代替字符串3.14159265.在程序中出现的是PI,在编译前预处理时,将所有的PI都用3. 14159265来代替,即使用宏名来代替指定的字符串。这一过程又称为宏替换或称为宏展开.例6.1给出半径求圆的面积。 执行该程序,出现如下信息:#dfine PI 3.1415

4、9265main ( ) fioat r, s, Printf(Input radius;) scanf(%f,&r); A=PI *r*rPrintf(:a=%.4fn:,a);执行该程序,出现如下信息:Input radius; 5 输出结果如下 s=78. 5398 说明:该例中,开始率义了符号常量PI,它是用宏定义来实现的。程序中出现的PI,在编译前预处理时将用3.14159265来替换。 2.使用简单宏定义时的注意事项 (1)宏定义中的标识符)(即宏名)一般习惯用大写字母,以便与变量名区别。这样。在C语言程序的各表达式语句中,凡是大写字母的标识符(指全部大写字母)一般是符号常量。但是

5、,宏定义中的宏名也可以用小写字母。 (2)宏定义是预处理功能中的一种命令,它不是语句。因此。行末不需加分号。如果加了分号,则该分号将作为所定义的字符串的一部分,即按字符串的一部分来处理。 (3)宏替换是一种简单的代替,替换时不作语法检查。如果所定义的字符申中有错,例如,将数字。,误写为字母。,预处理照样代换,并不报错,而在编译中进行语法检查时才报错。因此,要记住宏替换操作只是简单的代换,用宏定义时的字符串来替换其宏名。 (4)宏定义中宏名的作用域为定义该命令的文件中,并从定义时起,到终止宏定义命令( #undef() 其甲,是标识符,一般习惯上用大写字母,是由一个或多个参数组成的,多个参数之间

6、用逗号分隔;(宏体)是一个字符串,其中包含中所指定的参数,它可以是由若干个语句组成的。该命令末尾一般不加分号。 带参数的宏定义在宏替换时。不是简单的用宏体替换宏名,而是用实参替换形参.这里所说的实参是指程序中引用宏名的参数,而形参是指宏定义时,宏名后边参数表中的参数。 例如, #define sQ(x)x*x 在程序中出现下述语句: A=SQ(5); 这里,在宏定义中参数x是形参,而程序中SQ(5)的S是实参,宏替换时,将用5来替换x,其结果如下: a=5 * 5; 又例如, #define ADD(x,y) x十Y 在程序中出现下述语句; A=ADD(5,3); 宏替换后结果如下: a=5十

7、3; 如果在上述宏定义下,程序中出现如下语句; b=ADD(a+1,b一1); 宏替换后结果如下: B=a+1+b-1 由此可见,带参数的宏定义是这样替换的:按照宏定义中所指定的宏体从左至右用程序中出现的宏的实参来替换宏体中的形参,对非参数字符,则保留。宏中的实参可以是常量、变量或表达式。2.使用带参数的宏定义应该注意的事项 (1)在宏定义时,宏名与左圆括号之间不能出现空格符,否则空格符后将作为宏体的一部分。例如: #define ADD (x,y) x十Y 将认为ADD是不带参数的宏名,而字符串(x, y) x+y作为宏体。显然,这不是原来的含意。因此,宏名后与左圆括号间一定不能加空格符。

8、(2)宏体中,各参数上加括号是十分重要的。例如: #define SQ(x) x*x 当程序中出现下列语句, A=SQ(a十1); 替换后,则为; a=a+1*a+1 而不能将替换的结果写成 a=(a十1)*(a+1); 如果要将替换后结果写成上述形式,则需要将宏定义改写为: #define SQ(x) (x),(x) 由此可见,在宏定义中,对宏体内的形参外向加上括号是很重要的,它可以避免在优先级上可能出现的问题。 对上述宏定义最好写成下述形式: #define SQ(x)(.x)*(x ) 这里的圆括号是很有用的。例如,在有如下语句时, m=50/SQ(b十1); 替换后结果如下: m= 5

9、0/(b十1)*(b+1); (3)带参数的宏定义与函数的区别 带参数的宏定义和函数尽管在形式上非常相似,特别是当宏名使用小写字母时,出现在程序中很难区别出来是带参数的宏定义还是函数。但是,这二者是根本不同,它们之间的区别概述如下: 定义形式上不同。带参数的宏定义的定义格式前面讲过了,它是通过预处理命令ce-fine来定义的。它的作用域是在定义它的文件内,并从定义处开始。而函数的定义格式在本书函数和存储类1章中描述过了。它的作用域分为程序级的和文件级的两种。 处理时间上不同。宏定义是在编译预处理时处理的,处理后再进行编译。而函数是在执行时处理的。它们二者占用的是不同阶段的时间。 处理方式_卜。

10、不同。带参数的宏定义在进行宏替换时,用实参来代替形参,这里只是简单替换,并不做语法上的检查。而函数调用时,是将实参的值赋给形参,要求对应类型一致。宏定义中在参数替换时,不要求类型一致仁 时间和空间的开销上不同。带参数的宏定义,是在通常的编译之前完成替换的,因此它在该程序的目标代码的形成上并没有影响。函数调用是在执行时进行的,因此,采用函数调用的方式可以减少该程序的目标代码,所以,在空间的开销上可以减少。但是,函数调用要有额外的时间上的开销。因为调用前要保留现场,调用后又要恢复现场,因此函数调用时间开销要比带参数的宏定义大。带参数宏定义在使用中比函数时间开销小是一个重要特征。 类型的要求上不同。

11、带参数的宏定义对形参的类型不必说明,它没有类型的限制。而函数的形参在定义时必须进行类型说明。例如,两个数相减的操作用带参数的宏定义和函数分别定义如下: 用带参数的宏定义格式如下: 抹define MINU (x,y)(x)一(Y) 用函数的定义格式如下: minu(x,y) Int x,y ( return (x一y); 该函数只能进行两个lnl型数值相减的运算。而。上述的宏定义可以进行两个。har型量的相减,也可以进行两个int型数的相减。还可以进行两float型数的相减,因为它没有类型的限制通过上述对于带参数的宏定义和函数之间区别的分析,不难看出两者各有特点。对于同一个间题一可以采用两种不

12、同的表示形式,那么到底选择哪一种更好些呢?一般说来,在功能比较简单的情况一下,选用带参数的玄定义能更好些,特别是在需要反复引用的情况下,用宏定义的时间开销较少。例如,比较两个整数的大小,并输出最大的,可用如下的宏定义来实现: #define fl(a,b)printf(%dn,ab?;b); 又例如,计算一个自然数的立方值,可用如下的宏定义实现: #define f2(a)printi%dn,a*a*a); 功能比较复杂的还是选用函数来定义。6.2.3 宏定义的应用 在C语言程序中,宏定义主要用于下述几个方面。 (1)符号常耸的定义 C语言中的常觉一般都用符号常量表示,这样不仅书写简便,而且易

13、于修改、易于移植,还可以使标识符有更明显的含意。例如, #define PI 3.14159265 #define E 2.71828 #define EPS 1.0e一9 #define MAX 32767 #define TRUE 1 #define FALSE 0 等等。 (2)功能简单使用频繁的情况卜,用带参数的宏定义比用函数可以提高速度。因为函数调用要花费额外的时间开销。 (3)在多数情况下,为了书写简练,程序易读而采用宏定义例6.4分析下列程序输出结果,并说明宏定义在该程序中所起的作用。 #define F1%dn #define F2%d,%dn #define PRl(a)pr

14、int3(1,a) #define PR2t(a.b) print(F2,a,b); main) int x+y,z; x=5; y=5*x; z=x*y; PR1(x); PR2(y,z); PR1(2,y); PR2(x+5,z/5) 执行该程序输出的结果如下: 5 25.30 50 10.6 说明: (1)该程序前面有4条宏定义命令。前两条是简单宏定义,后两条是带参数的宏定义。这4条宏定义命令都是有关标准文件的格式输出的。 (2)程序中的最后4条语句是输出显示结果的语句,由于引用了宏定义命令,使得该输出语句简练、清晰。由于在C语言程序中,输出显示结果语句用得较多,并且可选用不同的参数个数

15、,如果能使用宏定义命令使之简化,将给书写带来方便。特别是这里使用一次文件包含命令(下面讲述)将宏定义部分写在一个。h(头文件)文件内,程序需要时只要包含进去就可以了,这样将会更加简便。6.3.1 文件包含命令的格式和功能 文件包含命令是C语言程序常用的一条预处理命令,它的格式如下: # include(文件名) 其中,include是关键字,(文件名)是被包含的文件名,这里要求使用文件全名,包括路径名和扩展名。 文件包含的功能就是将指定的被包含文件的内容放置在文件包含命令出现的地方。该命令可写在程序的任一位置,但是一般写在一个文件的开头,这是一种明智的选择。因为该命令在何处出现,所包含的文件内

16、容就被放置到该命令出现的位置,这就相当于将被包含文件的内容插入到该命令的地方。而被包含的。h文件中往往是一些该程序所需要的一些说明或定义,它包括符号常量的定义、类型定义、带参数的宏定义、数组、结构、联合和枚举的定义等等,它还可以包含外部变量的定义、函数的定义和说明等等。这些内容程序中将要用到,显然放在程序前面比放在中间和后面要好些。 文件包含的用途在于减少程序人员的重复劳动,使得C语言程序更加简洁,提高程序的可读性。但是,如果对文件包含命令使用不当,会增加程序的代码长度,包含了一些该程序所不需要的内容。因此,选择包含的文件时要慎重,定义被包含的文件时要短小。 6. 5 将例6. 4中的宏定义部

17、分写在一个print.h文件中,当程序需要时,将它包含进去。其做法如下: 定义。h文件名为print.h,它将包含有关输出显示结果的宏定义,其内容如下: #define F1%dn #define F2%d,I%dn #de,ine PR1(a)printf(Fl,a) #define PR2(a,b) printf(F2,a,b) 程序内容如下 #include print.h Main() int x,y,z; X=5; y=5*x: z =x+y; PR1(x); PR2(y,Z); PR12,Y); PR2(x+5,z/5) 执行该程序的输出结果与例6. 4的结果相同。 该程序中在开头

18、使用了文件包含命令,将文件print.h包含在该程序的开头。从程序书写角度来看只使用了一条文件包含命令便可代替该文件(指print. h文件)中的4条宏定义命令,可见书写简单了。print. h文件还可以用于其他程序中,如果某个程序需要该文件的内容,只要使用一条文件包含命令就可以了。 6.3.2使用文件包含命令时应注意事项、 (1)一个文件包含命令只能包含一个文件。如果某个程序需要包含多个文件,则可使用多条文件包含命令。例如,下列写法是错误的, #includ xy. h mn. h 而改写成下列形式是正确的, #includexy. h #includemn. h 其前后顺序取决于被包含文件

19、内容间的相互关系。如果两个被包含文件内容相互无关,则书写的前后顺序也无关。如果一个文件中要使用另一个文件的内容,则另一个文件要写在前面。 (2)文件包含的定义是可以嵌套的。所谓文件包含定义的嵌套是指在一个被包含的文件中还可以包含有其他文件。例如, 文件filel. c的内容如下: #include filet. h 而被包含的文件#file2.h的内容如一下: #include file3. h 这便是文件包含的嵌套,它可以等价于: 文件filet c的内容如下: #include,file3. h #includefile2. h 按上述顺序写比较安全。 (3) 文件包含命令中,引用的被包含

20、文件有下面两种方式: 方式一: # include(文件名 方式二: # include文件名, 这两种方式中,文件名都要求是全名,方式一中用一对尖括号将文件名括起,它表示所引习的被包含文件是系统提供的,并放在指定目录下的。h文件。例如, #include stdio. h) #include math. h) 等等。 这种方式引用时,系统将到指定的目录去查找系统提供的。h文件。 方式二是用一对双引号将文件名括起,它表示所引用的被包含文件可能是用户自己定义的文件,并放在当前目录下或系统可自动查找的目录下。对这种引用的文件,系统先在当前目录下或用nos命令(PATH)连起来的通用目录下查找,如果

21、找不到再到系统指定的目录下查找带因此,要求编程人员对自己定义的被包含文件,引用时使用双引号,而系统提供的。h文件最好使用尖括号,这样查找可能快些。 (4)被包含的文件可以是任意的源文件,不一定必须是。h文件,也可以是。c文件, 例6.6 使用文件包含命令将一个。c文件包含在另一个。c文件之中。 f1. c文件内容如下: add(x,y int x,y; int z; z =x+y; return(z); f2.c文件内容如下: #Include fl.c main () int a,b; a=5; b=10; printf( %dn,add (a,): 执行f2一文件后,将获得如h结果: 15

22、 在f2.c文件的开头就使用文件包含命令将f1.c一文件包含了进去,这就相当于将fl.c文件的内容插入到f2. c文件中main( )的前边。 (5)为提高程序的可移植性,编程时事先将一些在不同环境或条件厂需要修改的量或需要修改的部分放在一个被包含的文件中,以后为适应某种环境需要修改时。可以只修改包含文件中的内容,这将为该程序的移植提供了方便。 6.4.1条件编译的常用命令格式 条件编译的常用命令格式有如下三种。 格式一: #ifdef #else #endif 其中,ifdef,else和endif是关键字。(标识符少是指是否使用 defin命令定义过。和是由语句或命令组成的程序段。 该格式的功能描述如下; 当被宏定义时,中的语句或命令参加编译;否则程序段2)中的语句或命令参加编译,该格式中,#else是可以省略的,则变成下列格式: #ifdef (程序段) #endif 格式二: #ifndef #else #endif 该格式与格式一大致相同,只是第一个关键字中不一样。 该格式的功能是:如果未被宏定义

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1