版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章〓预处理命令10.1〓知识要点回顾10.1.1〓C语言的预处理在C语言中,并没有任何内在的机制来完成以下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。要完成这些工作,就需要使用预处理程序。尽管在目前绝大多数C语言的编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程先于编译器对源代码进行处理。预处理过程扫描源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换,产生新的源代码提供给编译器。预处理过程还会删除程序中的注释和多余的空白字符。C语言的预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。C语言中常用的预处理指令如表10-1所示。表10-1〓C语言常用预处理命令指令用途#空指令,无任何效果#include包含一个源代码文件#define定义宏#undef取消已定义的宏#ifdef如果宏已经定义,则编译下面代码#ifndef如果宏没有定义,则编译下面代码#if如果给定条件为真,则编译下面代码#else用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后面的代码#endif结束一个#if…#else条件编译块10.1.2〓文件包含#include预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。标准C编译器至少支持八重嵌套包含。在程序中包含头文件有两种格式:#include<my.h>#include"my.h"第一种方法是用尖括号把头文件括起来。这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。第二种方法是用双引号把头文件括起来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。采用两种不同包含格式的理由是:编译器安装在公共子目录下,而被编译的应用程序在它们自己的私有子目录。一个应用程序既会包含编译器提供的公共头文件,也会包含自定义的私有头文件。采用两种不同的包含格式,可以使编译器能够在多个头文件中区别出一组公共的头文件。预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。例如:#defineMYC#include"my.c"#undefMYC#include"my.c"以上代码中my.c被两次包含,但在my.c中可以根据MYC是否定义(define)而决定两次包含时编译的代码不同。为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。例如,在my.h文件中使用如下预处理命令结构:#ifndefMY_H#defineMY_H〓……//被编译语句#endif当在其他文件中多次使用#include"my.h"时,my.h文件中的被编译语句部分将只被编译一次。10.1.3〓宏定义宏是一个被定义了用来代表特定内容的标识符。预处理过程会把源代码中出现的宏标识符替换成宏定义时的值。宏最常见的用法是定义代表某个值的全局符号。宏的第二种用法是定义带参数的宏,这样的宏可以像函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。1.#define指令#define预处理指令是用来定义宏的。该指令最简单的格式是:首先申明一个标识符,然后给出这个标识符代表的代码。在后面的源代码中,就用这些代码来替代该标识符。作为一种约定,习惯上总是全部用大写字母来定义宏,这样易于把程序中的宏标识符和一般变量标识符区别开来。例如:#defineMAX_NUM10intarray[MAX_NUM];for(i=0;i<MAX_NUM;i++)/*……*/在这个例子中,对于阅读该程序的人来说,符号MAX_NUM就有特定的含义,它代表的值给出了数组所能容纳的最大元素数目。程序中可以多次使用这个值。如果想要改变数组的大小,只需要更改宏定义并重新编译程序即可。宏表示的值可以是一个常量表达式,其中允许包括前面已经定义的宏标识符。例如:#defineX1#defineY2#defineZ(X+Y)上面的宏定义使用了括号,尽管它们并不是必须的,但出于谨慎考虑,还是应该加上括号。例如:s=Z*Y;预处理过程把上面的一行代码转换成:s=(X+Y)*Y;并进而转换成:s=(1+2)*2;如果没有那个括号,就转换成:s=X+Y*Y;并进而转换成:s=1+2*2;可以看出两者区别非常大。宏还可以代表一个字符串常量。例如:#defineNIT"南昌工程学院"2.带参数的#define指令带参数的宏和函数调用看起来有些相似。例如:#defineAdd(x,y)((x)+(y))在使用时,可用任何数字表达式甚至函数调用来代替参数x和y。例如,假设a和b已经定义了,则以下的代码:a=4;b=7*Add(5,6+a)*8;将会转换成:a=4;b=7*((5)+(6+a))*8;在这里仍然要提醒大家注意括号的使用。若上面的宏定义不带括号:#defineAdd(x,y)x+y则以下的代码:a=4;b=7*Add(5,6+a)*8;将会转换成:a=4;b=7*5+6+a*8;10.1.4〓条件编译指令条件编译指令将决定哪些代码被编译,而哪些不被编译。通常,可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。1.#if和#endif#if指令检测跟在其后的常量表达式(通常是一个宏),如果该表达式为真,则编译后面的代码,直到出现#else、#elif或#endif为止;否则不编译。#endif用于终止#if预处理指令。例如:#defineDEBUG0main(){〓#ifDEBUG〓〓printf("Debugging\n");〓#endif〓printf("Running\n");}上面的程序代码中,由于程序定义DEBUG宏代表0,所以#if条件为假,不编译后面的代码直到#endif,所以程序直接输出Running。如果去掉#define语句,效果是一样的。2.#ifdef和#ifndef#ifdef表示如果其后的宏已经定义,则编译下面代码;#ifndef则表示如果其后的宏没有定义,则编译下面代码。例如:#defineDEBUGmain(){〓#ifdefDEBUG〓〓printf("yes\n");〓#endif〓#ifndefDEBUG〓〓printf("no\n");〓#endif}以上程序运行结果为yes。若将#defineDEBUG删除,运行结果为no。#ifdefined等价于#ifdef;#if!defined等价于#ifndef3.#else#else指令用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后面的代码。#endif指令将中指上面的条件块。例如:#defineDEBUGmain(){〓#ifdefDEBUG〓〓printf("Debugging\n");〓#else〓〓printf("Notdebugging\n");〓#endif}以上程序运行结果为Debugging。若将#defineDEBUG删除,运行结果为Notdebugging。10.2〓实训内容实验一〓验证性实验一、实验目的掌握常用预处理指令的使用方法。二、实验设备和仪器(1)IBMPC或兼容计算机。(2)Windows9x/2000/XP操作系统。(3)VisualC++6.0。三、实验内容(一)调试程序11.实验要求调试程序,验证程序中如何多次包含只能包含一次的my.h头文件。2.程序代码ex10_1.c#include<stdio.h>#include"my.h"#include"ex10_1.h"main(){〓printf("a=%d\n",a);〓printf("MAX(3,5)=%d\n",MAX(3,5));〓printf("MAX(3,5,4)=%d\n",MAXEX(3,5,4));}ex10_1.h代码如下:#include"my.h"#defineMAXEX(x,y,z)(MAX(x,y)>z?MAX(x,y):z)my.h代码如下:inta=3;#defineMAX(x,y)(x>y?x:y)3.实验步骤步骤一:在D盘的根目录中创建一个以你的学号命名的文件夹,如D:\200710003。步骤二:打开“MicrosoftVisualC++”软件,分别建立ex10_1.c、ex10_1.h和my.h文件,输入源代码并保存。步骤三:编译ex10_1.c程序,系统报错,如图10-1所示。图10-1〓ex10_1程序编译报错步骤四:将my.h文件修改如下:#ifndef_MY_H〓#define_MY_H1〓inta=3;〓#defineMAX(x,y)(x>y?x:y)#endif步骤五:再次编译ex10_1.c程序,系统没有报错,程序运行结果如图10-2所示。图10-2〓ex10_1正确执行(二)调试程序21.实验要求调试程序,验证宏定义时带括号与不带括号的区别。。2.程序代码ex10_2.c#include<stdio.h>#defineX1#defineY2#defineZ(X+Y)main(){〓ints;〓s=Z*Y;〓printf("s=%d\n",s);}3.实验步骤步骤一:打开“MicrosoftVisualC++”软件,建立ex10_2.c文件,输入源代码并保存。步骤二:编译并运行程序,程序运行结果如图10-3所示。s的值等于(1+2)*2=6。图10-3〓ex10_2中宏定义带括号执行结果步骤三:将程序中的#defineZ(X+Y)中的括号删除,变成#defineZX+Y后,再次编译运行程序,程序运行结果如图10-4所示。s的值等于1+2*2=5。图10-4〓ex10_2中宏定义不带括号执行结果(三)调试程序31.实验要求调试程序,验证带参数宏定义的使用。2.程序代码ex10_3.c#include<stdio.h>#defineAdd(x,y)((x)+(y))main(){〓inta,b;〓a=4;〓b=7*Add(5,6+a)*8;〓printf("b=%d\n",b);}3.实验步骤步骤一:打开“MicrosoftVisualC++”软件,建立ex10_3.c文件,输入源代码并保存。步骤二:编译并运行程序,程序运行结果如图10-5所示。b的值为7*(5+(6+4))*8。图10-5〓ex10_3第一次执行结果步骤三:将程序中的:#defineAdd(x,y)((x)+(y))修改为:#defineAdd(x,y)x+y再次编译运行程序,程序运行结果如图10-6所示。b的值为7*5+6+4*8。图10-6〓ex10_3第二次执行结果(四)调试程序41.实验要求调试程序,验证#if和#endif的使用。2.程序代码ex10_4.c#include<stdio.h>#defineDEBUG0main(){〓#ifDEBUG〓〓printf("Debugging\n");〓#endif〓printf("Running\n");}3.实验步骤步骤一:打开“MicrosoftVisualC++”软件,建立ex10_4.c文件,输入源代码并保存。步骤二:编译并运行程序,程序运行结果如图10-7所示。图10-7〓ex10_4第一次执行结果步骤三:将程序中的:#defineDEBUG0修改为:#defineDEBUG1再次编译运行程序,程序运行结果如图10-8所示。图10-8〓ex10_48第二次执行结果(五)调试程序51.实验要求调试程序,验证#ifdef和#ifndef以及#else的使用。2.程序代码ex10_5.c#include<stdio.h>#defineDEBUGmain(){〓#ifdefDEBUG〓〓printf("Debugging\n");〓#else〓〓printf("Notdebugging\n");〓#endif}3.实验步骤步骤一:打开“MicrosoftVisualC++”软件,建立ex10_5.c文件,输入源代码并保存。步骤二:编译并运行程序,程序运行结果如图10-9所示。图10-9〓ex10_5第一次执行结果步骤三:将程序中的:#defineDEBUG修改为://#defineDEBUG再次编译运行程序,程序运行结果如图10-10所示。图10-10〓ex10_5第二次执行结果步骤四:将程序中的:#ifdefDEBUG修改为:#ifndefDEBUG再次编译运行程序,程序运行结果如图10-11所示。图10-11〓ex10_5第三次执行结果步骤五:将程序中的://#defineDEBUG修改为:#defineDEBUG再次编译运行程序,程序运行结果如图10-12所示。图10-12〓ex10_5第四次执行结果五、实验报告要求(1)写出以上五个程序的实验原理与考查知识点,并分析说明程序每次运行的结果。(2)写出在程序调试过程中遇到的问题和解决方法。实验二〓启发性实验一、实验目的(1)掌握预处理程序设计与调试的方法。(2)掌握预处理程序填空的方法。(3)掌握预处理程序改错技巧。二、实验设备和仪器(1)IBMPC或兼容计算机。(2)Windows9x/2000/XP操作系统。(3)VisualC++6.0。三、实验准备(1)预习C语言预处理常用指令的用法。(2)在D盘的根目录中创建一个以你的学号命名的文件夹,如D:\200710003。四、实验内容1.填空题甲乙丙丁四人同时开始放鞭炮,甲每隔t1秒放一次,乙每隔t2秒放一次,丙每隔t3秒放一次,丁每隔t4秒放一次,每人各放n次。函数fun的功能是根据形参提供的值,求出总共听到多少次鞭炮声作为函数值返回。注意,当几个鞭炮同时炸响,只算一次响声,第一次响声是在第0秒。例如,若t1=7,t2=5,t3=6,t4=4,n=10,则总共可听到28次鞭炮声。请在程序的下划线处填入正确的内容并把下划线删除,使程序得出正确的结果。源程序文件取名为ex10blank.c。不得增行或删行,也不得更改程序的结构!源程序如下:#include<stdio.h>/**********found**********/#defineOK(i,t,n)((____1___%t==0)&&(i/t<n))intfun(intt1,intt2,intt3,intt4,intn){〓intcount,t,maxt=t1;〓if(maxt<t2)maxt=t2;〓if(maxt<t3)maxt=t3;〓if(maxt<t4)maxt=t4;〓count=1;/*给count赋初值*/〓/**********found**********/〓for(t=1;t<maxt*(n-1);___2___)〓{〓〓if(OK(t,t1,n)||OK(t,t2,n)||OK(t,t3,n)||OK(t,t4,n))〓〓count++;〓}〓/**********found**********/〓return___3___;}main(){〓intt1=7,t2=5,t3=6,t4=4,n=10,r;〓r=fun(t1,t2,t3,t4,n);〓printf("T
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 自制水囊在剖宫产宫缩乏力出血中的临床应用
- 应急响应的统一指挥
- 二零二五年度道路设施更新改造合同3篇
- 二零二五年度个人乡村旅游消费贷款合同示范文本2篇
- 二零二五年度屋顶防水隔热节能改造合同4篇
- 2025年度新能源储能系统采购与安装合同范本3篇
- 2025版高层建筑消防系统改造合同协议书3篇
- 二零二五年度个人股权代持与公司解散合同3篇
- 不良反应上报流程
- 二零二五年度大学生创业项目融资借款合同
- 2025届安徽省皖南八校联盟高二物理第一学期期末统考试题含解析
- 第六章-主成分分析法
- 2024简单的租房合同样本下载
- 中考数学计算题练习100道(2024年中考真题)
- 新人教版五年级上册数学应用题大全及答案
- 【家庭教育】0-3岁婴幼儿早教训练方案
- 国家中长期科技发展规划(2021-2035)
- 经营范围登记规范表述目录(试行)(V1.0.2版)
- 2023年山东省威海市中考物理真题(附答案详解)
- 第八讲 发展全过程人民民主PPT习概论2023优化版教学课件
- 王崧舟:学习任务群与课堂教学变革 2022版新课程标准解读解析资料 57
评论
0/150
提交评论