cc程序设计第7章-编译预处理和位运算课件.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《cc程序设计第7章-编译预处理和位运算课件.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- cc 程序设计 编译 预处理 运算 课件
- 资源描述:
-
1、C/C+程序设计 C/C+程序设计程序设计第第7章章 编译预处理和位编译预处理和位运算运算第第7章章 编译预处理和位运算编译预处理和位运算 引言引言 编译预处理是C语言编译系统的一个组成部分。所谓编译预处理是指在对源程序进行编译之前,先对源程序中的编译预处理命令进行处理,然后再将处理的结果和源程序一起进行编译,以得到目标代码,预处理的实现方法是通过几种特殊的命令,在进行程序的编译之前,先对这些命令进行处理。这些预处理命令的介入,可以改进程序的设计环境,提高编程效率。编译预处理命令均以符号“#”开头,并且规定一行只能写一条预处理命令,命令结束不能使用分号,通常预处理命令都放在源程序的开头。在前面
2、几章的程序中,我们用到的#define、#include等命令都是编译预处理的应用。C语言提供了语言提供了3种预处理命令:种预处理命令:宏定义宏定义文件包含文件包含条件编译条件编译第第7章章 编译预处理和位运算编译预处理和位运算 C语言有两种宏定义命令,一种是不带参数的宏定义(也称符号常量定义),另一种是带参数的宏定义。7.1 编译预处理编译预处理-宏定义宏定义1.不带参数的宏定义不带参数的宏定义一般格式为一般格式为:#define 标识符标识符 字符串字符串说明:说明:1)通常宏名用大写字母表示,以示与普通变量区别。2)宏名与字符替换序列之间用空格符分隔。3)编译预处理时,在程序中进行宏替换
3、(也称宏展开),凡是 宏名出现的地方均被替换为它所对应的字符替换序列。4)编译预处理时只做简单的替换,不进行语法检查更不会做运 算,若字符串有错误,只有在正式编译时才会进行检查。5)没有特殊的需要,一般在预处理语句的行末不必加分号,若 加了分号,则连同分号一起替换。6)使用宏定义可以减少程序中重复书写字符串的工作量,提高 程序的可移植性。#define PI 3.14159f;area=PI*r*r;经过宏替换后:area=3.14159f;*r*r;,显然正式编译时会报告语法错误。通常当问题规模事先不能确定时,可使用宏定义来定义一个表示问题规模的符号常量。如:#define N 1007)宏
4、定义命令通常放在文件开头或者函数定义之前,宏名的作用域通常从定义开始到所在源文件结束。但使用#undef命令可提前强制终止某个宏的作用域。#define PI 3.14159fvoid main()#undef PI /结束宏名PI的作用域fun()PI的有效范围 这里,#undef PI 之后的代码范围,符号常量PI的宏定义就不再起作用了。8)进行宏定义时,在字符替换序列中可以引用已定义的其它宏名,宏展开时会进行层层替换。例如:#include#define PI 3.1415926f#define R 4.0f#define L 2*PI*R#define S PI*R*Rvoid mai
5、n()printf(L=%f,S=%f n,L,S);经过宏展开后,printf()函数调用语句被宏替换为:printf(L=%f n,S=%f n,2*3.14159f*4.0f,3.14159f*4.0 f*4.0f);2.带参数的宏定义带参数的宏定义带参数的宏定义不仅要进行简单的字符串替换,而且还要进行参数替换。一般形式为一般形式为:#define ()说明:说明:1)宏定义时,宏名与左括号之间不要出现空格,否则会将空格连同后面的所有替换字符序列都作为替换内容进行替换。例如:#define S (a,b)a*b 如果程序中有 y=S(x,y),则被展开为:y=(a,b)a*b(x,y)显
6、然这不是想要的结果。2)宏定义中的参数称为形参。程序中使用带参数的宏时,程序中的参数为实参,实参可以是常量、变量或表达式。宏展开时,将替换序列中的形参用相应位置的实参替换;若宏定义的替换序列中的字符不是形参,则在替换时保留。例如:#define S(a,b)a*barea=S(2,3);其中a和b称为形参,2和3称为实参,在宏展开时,把2、3分别代替宏定义中的a、b,a*b中的“*”号保留,因此宏展开后语句为“area=2*3;”。3)宏定义字符序列中的参数要用圆括号括起来,而且最好把整个字符串也用圆括号括起来,以保证在任何替换情况下都把宏定义作为一个整体,并且可以有一个合理的计算顺序,否则宏
7、展开后,可能会出现意想不到的错误。例如:#define S(r)3.14159*r*rarea=S(a+b);经过宏展开后变为“area=3.14159*a+b*a+b;”显然,由于宏定义时,对r没有加圆括号造成与设计的原意不符。那么,为了得到形如:area=3.14159*(a+b)*(a+b);就应该在宏定义时给字符序列中的形参加上圆括号,即:#define S(r)3.14159*(r)*(r)【例例7-1】从键盘输入两个数,输出较小的数。#include#define MIN(a,b)(a)(b)?(a):(b)void main()int x,y;printf(Please inpu
8、t two integers:);scanf(%d%d,&x,&y);printf(MIN=%d n,MIN(x,y);类型类型区别区别函数函数带参数的宏带参数的宏是否计算是否计算实实参参的值的值先计算出实参表达式的值,然后传递给形参变量。不计算实参表达式的值,直接用实参原样进行简单的替换。何时进行处理、何时进行处理、分配内存单元分配内存单元在程序运行时进行值的处理、调用函数时分配临时的内存单元。预编译时进行宏展开,不分配内存单元,不进行值的处理。类型要求类型要求实参和形参要有类型声明,且二者类型要匹配。不存在类型问题,只是一个符号表示。调用情况调用情况函数的代码仅存在一个拷贝,对函数较大、调
9、用次数较多时比较合算,但调用函数时会产生时间和空间的开销。在程序源代码中只要遇到宏符号,都将其进行宏替换,调用宏时没有时间空间的开销。但调用次数过多时会使程序代码加长很多。参数传递方式参数传递方式有按值传递和按址传递方式对宏不存方式问题,就是简单替换。3.带参数的宏与函数的区别带参数的宏与函数的区别7.1.2 文件包含文件包含文件包含是指一个源文件可以将另外一个源文件的全部内容包含进来,即将另一个C语言的源程序文件嵌入正在进行预处理的源程序中相应位置,一般形式为:#include 或者或者#include 文件名文件名 说明:1)“文件名”必须用一对尖括号或一对双引号括起来。2)使用尖括号和使
10、用双引号对应着不同的路径查找策略。尖括号尖括号:系统直接在规定的磁盘目录(通常为软件安装目 录下的Include子目录)查找文件。双引号双引号:首先在当前文件所在目录中查找文件,若没有找 到,再在操作系统的path命令设置的各目录中查找,若还没有找到,最后才在Include子目录中查找。3)一个#include命令只能指定一个被包含文件。7.1.2 文件包含文件包含4)若#include命令指定的文件内容发生变化,则应该对包含此文件的所有源文件重新编译处理。5)文件包含命令可以嵌套使用,即一个被包含的文件中可以再使用#include命令包含另一个文件,而在该文件中还可以再包含其它文件,通常允许
11、嵌套10层以上。【例例7-2】分析图7-1所示的几个C源文件之间的包含关系。#include file2.c file1.c中其余代码#include file3.c file2.c其余代码file3.代码cfile1.cfile2.cfile3.c分析:分析:通过#include“file3.c”命令,使file3.c的代码被加入到文件file2.c中,而#include “file2.c”又使file2.c被加入到 file1.c中,因此,通过预处理后,在文件“file1.c”中既有“file2.c”的代码也有“file3.c”的代码。两种形式:指定表达式真假值指定表达式真假值 或者:或者
展开阅读全文