C语言程序设计案例式教程-第10章 预处理_第1页
C语言程序设计案例式教程-第10章 预处理_第2页
C语言程序设计案例式教程-第10章 预处理_第3页
C语言程序设计案例式教程-第10章 预处理_第4页
C语言程序设计案例式教程-第10章 预处理_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第10章预处理《C语言程序设计案例式教程(第2版)》学习目标/Target掌握不带参数的宏,能够定义不带参数的宏掌握宏的取消,能够取消程序中不再使用的宏掌握带参数的宏,能够定义带参数的宏以实现更复杂的功能学习目标/Target掌握文件包含,能够通过文件包含调用已经定义好的功能程序掌握条件编译指令的使用,能够使用常用的条件编译指令实现程序的编译简化了解断言,能够说出断言的作用及断言如何取消章节概述/Summary在C语言中,除了前面介绍的语句之外,还有一种特殊的语句,即预处理语句,这类语句的作用不是实现程序的功能,而是给C语言编译系统提供信息,通知C编译器对源程序进行编译之前应该做哪些预处理工作。C语言提供的预处理语句主要包括宏、文件包含和条件编译等。本章将针对预处理语句进行详细讲解。目录/Contents案例10-1环保购物袋案例10-2交换数组元素案例10-3包装输出目录/Contents案例10-432还是64?案例10-5劝学案例10-6拒绝除零环保购物袋案例10-1【案例10-1】环保购物袋(1)掌握不带参数的宏,能够定义不带参数的宏(2)掌握宏的取消,能够取消程序中不再使用的宏学习目标案例描述本案例要求编写一个程序,模拟选择环保购物袋购物的场景,具体要求如下。(1)定义数组表示环保购物袋,用于存储商品。数组大小就是环保购物袋的大小。(2)从键盘输入要购买的商品,将商品存储到数组中。购买完成之后,在控制台输出所购买的商品。知识需求定义数组不知道数组大小定义变长数组宏定义需要知识讲解1.不带参数的宏定义宏定义格式如下。#define标识符字符串用于定义宏宏名宏体宏定义示例。#definePI3.1415926 //宏定义printf("%f\n",PI); //使用宏知识讲解1.不带参数的宏定义如果在程序中使用了宏,程序在编译时期会将宏替换为它定义的值,这个过程称为预处理,由预处理器完成。预处理示例。#definePI3.1415926 //宏定义printf("%f\n",PI); //使用宏//宏PI预处理之后printf("%f\n",3.1415926);如果程序中有很多地方用到PI,预处理器会将所有的PI都替换为3.1415926。如果需要更换PI的值,只更改宏定义即可。知识讲解脚下留心:宏定义注意事项1宏定义末尾不能加分号,否则分号将被视为宏体的一部分,预处理时会发生错误。#defineMAX20;//......if(result==MAX) printf("equal");错误示例。#defineMAX20;//......if(result==20;) printf("equal");预处理知识讲解2宏定义中如果出现运算符,需要在合适地方加上括号。否则预处理会出现错误。#defineS3+4//......a=S*c;错误示例。#defineS3+4//......a=3+4*c; //需要加上括号预处理脚下留心:宏定义注意事项知识讲解3宏定义允许嵌套,宏定义中的字符串中可以使用已经定义的宏名。#definePI3.141592 //定义宏PI#definePPI*5

//嵌套定义宏printf(“%f”,P); 宏定义嵌套示例。#definePI3.141592#definePPI*5printf(“%f”,3.141592*5);预处理脚下留心:宏定义注意事项知识讲解4宏定义不支持递归#defineMAXMAX+5

错误示例。脚下留心:宏定义注意事项知识讲解2.取消宏宏定义可以取消,取消宏定义的指令为#undef,预处理器在编译源代码时,发现#undef指令,那么#undef后面这个宏就会被取消,无法生效了。#undef宏名称知识讲解多学一招:预定义宏stdio.h标准库定义了五个关于源程序编译信息的宏,这5个预定义宏各有不同的作用。预定义宏说明__DATE__定义源文件编译日期的宏__FILE__定义源代码文件名的宏__LINE__定义源代码中行号的宏__TIME__定义源文件编译时间的宏__FUNCTION__定义当前所在函数名的宏案例实现定义宏N表示要购买的商品数量,即要选择的环保购物袋的大小。定义一个字符串数组commodities用于存储购买的商品,数组大小为N。循环遍历数组commodities,从键盘输入要购买的商品。输入完成之后,输出该数组中的商品。010203案例实现2.完整代码本案例中可以实现的效果图如下。intmain(){请参考案例10-1完整代码}代码实现交换数组元素案例10-2【案例10-2】交换数组元素掌握带参数的宏,能够定义带参数的宏以实现更复杂的功能学习目标案例描述在前面章节的学习过程中,有不少数据交换的案例,数据交换在实际编程中非常常用,除了简单的两个数据交换,有时也会交换数组之间的元素。本案例就要求编写一个程序,依次交换两个一维数组中的元素,数组元素的交换要求使用宏定义实现。知识需求数组元素交换宏定义实现无参宏定义只能定义固定内容,但数组元素在不断改变有参宏定义知识讲解带参数的宏除了不带参数的宏,C语言还提供了带参数的宏。#define标识符(参数1,参数2,…)字符串带参数的宏定义示例。#definePI3.14 //定义宏PI#defineCOMP_CIR(x)2*PI*x

//定义带参数的宏COMP_CIRintmain() {

doubler=1.0;

printf("2*pi*r=%f\n",COMP_CIR(r));//引用宏COMP_CIR

return0;

}知识讲解带参数的宏除了不带参数的宏,C语言还提供了带参数的宏。#define标识符(参数1,参数2,…)字符串宏定义预处理之后。#definePI3.14 //定义宏PI#defineCOMP_CIR(x)2*PI*x

//定义带参数的宏COMP_CIRintmain() {

doubler=1.0;

printf("2*pi*r=%f\n",2*3.14*r);return0;

}知识讲解带参数的宏带参数的宏定义用法类似函数,但两者有本质区别。VS宏定义预处理期间执行。没有参数类型。不分配内存,无值传递。运行速度快。有参数函数编译运行时执行。需要定义参数类型。分配内存,有值传递。运行速度慢。知识讲解带参数的宏使用带参数的宏时,要注意参数替换问题。#defineABS(x)((x)>=0?(x):-(x)) //定义宏计算x的绝对值doublex=12;printf("ABS(++x)=%f\n",ABS(++x));

//宏ABS计算++x的绝对值#defineABS(x)((x)>=0?(x):-(x)) //定义宏计算x的绝对值doublex=12;printf(“ABS(++x)=%f\n”,((++x)>=0?(++x):-(++x))));//结果14,错误

预处理案例实现123定义带两个参数的宏定义,功能为交换两个参数。定义两个数组,给它们的元素赋值。利用带参宏定义,交换数组元素的值并打印到屏幕上。案例实现2.完整代码本案例中可以实现的效果图如下。intmain(){请参考案例10-2完整代码}代码实现包装输出案例10-3【案例10-3】包装输出掌握文件包含,能够通过文件包含调用已经定义好的功能程序学习目标案例描述生活中有各种各样的包装,同样在程序设计中,也会有各种各样的包装。例如,在程序设计中,经常会输出一些数据,而且输出的数据各种类型都有,频繁的调用输出函数,书写会比较繁琐,那么本案例就要求设计一个头文件,将常用的输出模式都写进头文件中,定义为简单的宏,方便编写代码。知识需求定义头文件,使用头文件中的内容,需要包含相应头文件。这就需要学习头文件包含预处理语句。知识讲解文件包含文件包含就是将一个源程序文件包含到另外一个源程序文件中。#include<文件名>#include“文件名”

编译系统将在系统指定的路径下搜索尖括号(<>)中的文件系统首先会在用户当前工作目录中搜索双引号("")中的文件,如果找不到,再按系统指定的路径进行搜索。知识讲解文件包含文件包含应用示例。#defineNUM15foo.h文件#include<stdio.h>#include"foo.h"intmain(){

intnum=NUM;

printf("num=%d\n",num);

return0;

}project.c文件//插入stdio.h标准库文件内容#defineNUM15intnum=15;printf("num=%d\n",num);intmain(){

intnum=NUM;

printf("num=%d\n",num);

return0;

}预处理案例实现12定义头文件foo.h,在foo.h文件中定义int、double/float、char和字符串的输出形式,分别定义为宏INT(x)、DOUBLE(x)、CHAR(x)和STRING(x)。在其他文件中包含头文件foo.h,输出不同类型的数据。案例实现2.完整代码本案例中可以实现的效果图如下。intmain(){请参考案例10-3完整代码}代码实现32还是64?案例10-4【案例10-4】32还是64?掌握#if/#else/#endif指令的使用,能够使用#if/#else/#endif条件编译指令实现程序的编译简化学习目标案例描述本案例要求编写一个程序,模拟判断程序运行环境,如果是32位系统,就输出“程序运行环境为32位平台”;如果系统是64位系统,就输出“程序运行环境为64位平台”。知识需求判断程序运行环境if…else语句编译效率较低条件编译知识讲解#if/#else/#endif指令#if#else#endif指令根据常数表达式决定某段代码是否执行。通常情况下,#if指令、#else指令和#endif指令结合在一起使用。#if常数表达式

程序段1#else

程序段2#endif案例实现010203定义两个宏分别表示Windows32位和64位平台。定义宏SYSTEM表示其中某个平台。使用条件编译指令判断SYSTEM值,若值为32位平台,就输出32位平台提示信息;若值为64位平台,就输出64位平台提示信息。案例实现2.完整代码本案例中可以实现的效果图如下。intmain(){请参考案例10-4完整代码}代码实现劝学案例10-5【案例10-5】劝学掌握#ifdef指令和#ifndef指令的使用,能够使用#ifdef指令和#ifndef指令编译指令实现程序的编译简化学习目标案例描述本案例要求编写一个程序进行劝学,在程序中可以定义宏HARDWORKING表示勤奋努力,INEXERTION表示虚度光阴。如果程序中定义了努力勤奋或者没有虚度光阴,就在控制台输出鼓励赞美之言;如果没有定义努力勤奋或者虚度了光阴,就在控制台输出激励之言。本案例要求使用条件编译实现。知识需求宏HARDWORKING宏INEXERTION#ifdef和#ifndef指令判断两个宏是否定义知识讲解1.#ifdef#ifdef指令用于判断某个宏是否被定义。#ifdef宏名

程序段1#else

程序段2#endif宏被定义,则执行程序段1,否则执行程序段2知识讲解1.#ifdef#ifdef指令用于判断某个宏是否被定义。#definePI3.14#ifdefPIprintf("定义了宏PI\n");#elseprintf("未定义宏PI\n");#endif知识讲解2.#ifndef#ifndef指令用来确定某一个宏是否未被定义,它的含义与#ifdef指令相反,如果宏没有被定义,则编译#ifndef指令下的内容,否则就跳过。#ifndef宏名

程序段1#else

程序段2#endif知识讲解2.#ifndef#ifndef指令用法示例。#defineDEBUG#ifndefDEBUG printf("输出调试信息\n");#else printf("不输出调试信息\n");#endif知识讲解2.#ifndef#ifndef指令可以解决头文件重复包含的问题。(1)定义foo.h文件structFoo{

inti;

};(2)定义bar1.h和bar1.c文件//bar1.h#include"foo.h"voidbar1(structFoof);//bar1.c#include"bar1.h"voidbar1(structFoof){}知识讲解2.#ifndef#ifndef指令可以解决头文件重复包含的问题。(3)定义bar2.h和bar2.c文件//bar2.h#include"foo.h"voidbar2(structFoof);//bar2.c#include"bar2.h"voidbar2(structFoof){}知识讲解2.#ifndef#ifndef指令可以解决头文件重复包含的问题。(4)定义main.c文件#include"foo.h"#include"bar1.h"#include"bar2.h"intmain(){ structFoof={1}; bar1(f); bar2(f); return0;

}知识讲解2.#ifndef编译程序,程序报错。foo.h中定义的structfoo重复包含,即foo.h重复包含知识讲解2.#ifndef解决问题的方法:对foo.h进行修改,使用#ifndef指令和#define指令组合判断foo.h中的内容是否已经定义。#ifndef_FOO_H_#define_FOO_H_structFoo{

inti;};#endif案例实现在程序中定义宏HARDWORKING,分别使用#ifdef指令和#ifndef指令判断是否定义了宏HARDWORKING,根据判断结果输出相应提示信息。1.案例设计案例实现2.完整代码本案例中可以实现的效果图如下。intmain(){请参考案例10-5完整代码}代码实现拒绝除零案例10-6【案例10-6】拒绝除零了解断言,能够说出断言的作用及断言如何取消学习目标案例描述在数学的除法运算中,零是不能作为除数参与运算的。在程序中编写除法功能时,如果不小心输入除数为零,在没有提示信息的情况下,很难排查出程序中的错误。针对除数为零的情况,本案例要求编写一个程序,实现除法运算,在实现除法运算时,要对除数进行判断,保证除数不为零。知识需求除数不为0对条件进行检测断言检测条件知识讲解1.断言C语言中的断言使用宏assert()实现,assert()包含在assert.h标准库中。voidassert(intexpression

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论