第一篇:C语言程序设计冒泡排序教学案例 杨进
C语言程序设计冒泡排序教学案例
永川职业教育中心
杨进
【案例背景】
排序是计算机学科中一项复杂而重要的技术,在各种软件中使用频率都很高,因此专家们研究了各种排序算法。在中职类设计课程教学中,常以冒泡排序来讲解排序的原理,它简单,但过程繁琐,传统教学很难激发学生兴趣,学生不易理解,也很难编写掌握冒泡排序。因此,如何合理设计教学过程,让学生掌握冒泡排序的思想和编程方法,又能发散思维,扩充知识,进而激发学生对编程课程的兴趣,是一个关键问题。
1、学情分析
学生已学习了程序设计的三种结构,学习使用了数组。但在学习排序算法的过程中学生可能会对数组变量的变化在理解上存在一定困难,在排序算法中,对双重循环内外层的作用及有关循环参数的设置可能会产生一些不合理或是错误,需要通过实践的体验进行强化使用规范。
2、教学目标
知识目标:掌握冒泡排序的原理;能结合冒泡排序的原理看懂冒泡排序的主要代码;理解冒泡排序的流程图;
能力目标:学会使用冒泡排序思想设计解决简单排序问题的算法;进一步理解程序设计的基本方法,进一步体会算法与程序实现的关系;
情感目标:培养学生分析问题、发现规律的能力,激发学生学习热情;培养良好的读程习惯;
3、教学重点、难点
重点:冒泡排序算法的基本思想,双重循环应用
难点:双重循环程序的解读,冒泡排序算法实现后对程序的理解
4、教学策略与手段
以循序渐进、层层深入为教学的指导方针,采用讲解法、演示法、讨论合作、分析归纳法引导学生参与思考,由特殊到一般,有效地突出重点突破难点,逐步深化对冒泡算法、循环思想和执行过程的理解。
1
5、课前准备
PPT课件、冒泡排序的视频文件。【案例描述】
师:在前面的学习中,我们学过了用EXCEL进行一些简单的数据处理方法,请同学们说说看你是怎么对同学的成绩排次序的?
生:先选好数后,点排序就行了。
师:是的。只要用EXCEL的排序功能就可以了,点点鼠标就能完成。在前面的学习中,我们已经解开了很多单击鼠标就可以完成某一个任务的秘密,今天我们就来探访一下排序的秘密。
师:先让我们来做个舞蹈视频,同时要求同学们谈谈看后的自己的想法。并要请几位同学模拟示范。
这段真人编排的排序算法的舞蹈视频,非常生动有趣,能充分吸引学生的眼球,极大激发了学生的兴趣。
播放完毕,老师提问:请同学们说说你们看到了什么? 生:议论并说自己的想法。(冒泡排序的过程)
由于视频播放相对较快,为了让学生更好理解与参与,老师还根据具体情况请了四位涌跃分子来作下一个游戏。
请四位同学从前到后坐好并拿好老师给你们的数字,然后从后面开始两个两个比较你们手中的数,如果后面的同学数小的话就和前面的同学换一下座位,直到拿到最小数的同学坐在第一个位子为止。
现在开始,请其他同学注意观察。请同学们说说你们看到了什么? 生:议论并说自己的想法
师:我听到了同学们的发言了,你们都看到了最小数已经在最前面了,并且是经过了3次的比较。想一想,如果要让拿第二小的数的同学坐上第二个座位,还要进行几次的比较呢?(注意只能从后开始两两比较)请拿数的同学演示一下。几次?
生:两次
师:对了,是两次,比第一次少了一次。请四位同学回到座位。刚才我们通过四位
2
同学的演示其实给我们展示了一种数据排序的方法---冒泡法。那么什么是冒泡排序法呢?
冒泡排序法:是指把n个要排序的数看成一垂直列,从最下面的数开始两两比较相邻的两个数,把小的数向上换,经过n-1次处理以达到排序目的的一种排序方法。(课件展示)
分析总结学生的演示:(课件展示)第1次冒泡排序时 j 从 4 开始到2:
第2次冒泡排序时 j 从 4 开始到3:
第3次冒泡排序时 j 从 4 开始到4
如果用伪代码可表示为:
第1次冒泡排序时 j 从 4 开始到2: for(j=4;j>=2 ,j--)if(d[j] 3 for(j=4;j>=3 ,j--)if(d[j] 问:如果我们用一个变i(值分别为1,2,3)来记录冒泡的次数,请问能否将上述的三次代码合并成一段通用的代码呢? 生:能(学生讲伪代码)for(j= 4,j>=i+1,j--)if(d[j] 归纳分析引入核心代码: 当i=1到3时:(课件展示)for(j= 4;j>=i+1;j--)if(d[j] 那么,我们用我们学过的循环语句就可以把某一次的比较表示为:(课件展示)for(j= 4;j>=i+1;j--)if(d[j] 生:思考 师:其实,我们可以在刚才的循环外再加一层循环,使i也参与变化,以达到对次数的控制(课件展示) for(i=1;i<4;i++)for(j=4;j>= i+1;j--)if(d[j] 刚才我们已经讲解了4个数冒泡排序的代码,那么有n个数呢?(课件展示)for(i=1;i 4 for(j=n;j>= i+1;j--)if(d[j] 分析冒泡排序的源程序(用tc编辑器演示分析)为了进一步检验学生的情况,老师作了问题延伸: 编写一个评分系统的代码段:有10个评委,最后得分为去掉一个最高分与一个最低分后的平均分。(提示:排序后要将最小和最大的数去除,再累加其余各数并除以8)。 【案例反思】 1、本课时采用通过对冒泡排序的基本方法进行分析,利用视频、游戏等多种教学手段,采用正向讲解算法思想,总结规律,归纳算法等方法,一方面使学生顺利从排序的思想过渡到伪代码并到代码的书写,逐步引出双循环和冒泡排序的程序实现,另一方面培养学生观察算法,分析算法和使用算法的双向思维意识和发散思维能力,提高学生自觉能力和独立思考能力,体现了在课程教学中培养学生综合素质的教育思想。 2、老师要注意讲授时间,要能及时调节课堂气氛,防止学生课内思维疲劳。 5 《C语言循环程序设计—for语句》教学案例 漠河县职业技术学校 尘威威 《C语言循环程序设计—for语句》教学案例 漠河县职业技术学校 尘威威 C语言基础是中职计算机专业的一门必修课,也是要求计算机专业学生学习、掌握的一门重点课程,这门课程核心内容就是要让学生掌握一门编程的语言,学会编写简单的程序,能读懂C语言源程序。 案例背景: 在计算机应用专业教学中,C语言是一门理论与实践结合得比较紧的课程。要掌握和使用好这门语言,既要求学生有比较扎实的理论基础,又要具备较强的应用实践能力。如果只是按照传统的知识体系照本宣科,让学生理解这些枯燥的概念都难,更不要说达到良好的教学效果,而且易挫伤学生学习编程的积极性。因此,在教学中可以改为从案例入手,通过给学生演示、让学生模仿,在实际应用中去探究和领悟这些概念,并适时地加以归纳总结和进行概念的延伸,让学生在轻松愉快的气氛中学习新知识。所以从课程内容而言,案例教学是适用的,是切合学生的。 循环结构是程序设计三种基本结构的重中之重,而循环中的for循环是程序中运用最多的,也是较灵活的语句之一,它既是前面知识的延续,又是后面知识的基础,在知识构架中起着重要的衔接作用,如果不采用一些恰当有效的方法,学生在学习过程中会难以掌握。在教学过程中教师应结合一些有趣的程序,提高学生的学习兴趣,引导学生全身心地投入课堂。本文针对学生的实际情况,具体阐述for循环语句在具体编程时的灵活应用。 教学目标确定 (一)知识与技能 1、领会程序设计中构成循环的方法 2、能使用for循环语句编写C语言语句,并能运用for循环语句编写出正确的程序。 (二)过程与方法 C语言程序设计中for循环语句教学以行动导向教学为主线,通过“提出问题―分析问题―解决问题―问题扩展―讨论―总结归纳―实践”的程序,过渡到知识应用和练习。 本课采用多媒体课件进行教学,通过课件把文字和图片有机的结合,使学生在学习过程中更加容易理解,学习效率高。在课堂讨论和实践过程中,教师适当引导,学生主动探究、归纳总结学习内容,既有利于领会掌握新知识点,又能充分发挥学生的主体作用。在重点的突破上,采用范例比较教学法,给出具体的案例,让学生通过典型的例子掌握知识,同时通过用while、do while语句的所编写的程序进行比较,加深学生印象,让学生快速的掌握for循环语句的基本结构及使用方法。 (三)情感与价值观 1.让学生在自主解决问题的过程中培养成就感,为今后自主学习打下良好的基础。 2、培养学生学习的主动性,激发学生学习热情,以及培养团队合作的精神、自主探究,合作交流的学习方法,观察,乐于分析的学习态度。 教学重难点确定 C语言程序设计中for循环语句的重点是“for语句的结构”,分析题目意图(即算法分析),并用让学生便于理解的方式描述,学生掌握语句的结构和用法并不困难,难的是在实际的应用中那些时候该使用哪种循环来解决问题比较简洁、高效,所以我把本节课的难点确定为“for语句的应用”。 学情分析:本节课我主要针对计算机专业高三高考班的学生,在学这节课之前他们应准确掌握《C语言程序设计》中关于实现循环结构语句,如 for 或 while,do-while。并拥有能分析并描述简单算法如求累加,累乘的能力。 案例描述 案例1:教师将一张空白A4纸向学生展示,跟同学们说,今天老师给大家做个试验,让你们来猜一猜(学生的兴趣和精神一下就提起来了),然后老师边演示边讲解,将这张纸对折一下后几张?学生都能回答: 2张。继续发问,对折两下几张?学生:4张。对折三下呢?学生:8张。(这个时候学生充满疑惑,老师想干嘛呢,问这么简单的问题)接着老师提出问题:如果纸理想化的大,对折42下,这些纸的厚度将会多高? 这个教室一下就热闹起来了,学生们纷纷给出自己想像的答案,有些同学比划出手势:伸开双手说:有那么高,有人说桌子那么高的,有说房子那么高的。又有人马上否定,哪有那么高。有些同学拿起笔就开始算,算着算着就不知道该从哪儿下手了。 这个时候老师组织安静课堂,叫同学分组给出自己心里倾向的答案,可以估计,可不说理由。 四个小组分别给出的答案是:1:书桌那么高(大概50cm)。2:人的高度(大概170cm)。3:楼房的高度(大概3000cm)。4:大概10厘米。 老师不说哪一组对,只是问同学们,这个高度该怎么算? 接下来和同学一起分析得出以下结论: 1、纸张的厚度h? 2、有多少张纸n? 3、高度=h*n.解决问题1:同学自行测量(4组同学各自准备100页纸,测出总高度/100,取4个小组的平均值)。最后得出一张纸的厚度约=0.1mm。 这个环节的主要目的是让每个学生动手,锻炼他们的动手实践,合作交流的集体合作精神。 解决问题2:有多少张纸?2的42次方。接下来利用循环语句来做(即有42个2相乘)。 编写源程序 所用方法:学生自己编写,小组同学相互交流。 目的:培养并锻炼学生将心中已明确的算法落实到具体的程序语句上。 教师活动 这个时候巡查教室,检查并了解学生完成情况,对部分有小问题的同学给予及时帮助。 组上有成绩比较好的同学很快就把程序编写完毕,我看了一下,选了一个同学到教室机给大家调试展示。该同学给出的程序如下: main(){ int i,k=1;float s;for(i=1;i<=42;i++)k=k*2;/* k是纸张的张数 */ s=k*0.1*1.0e-6;/* 将mm转换成km */ printf(“将一张纸折42下的高度为:%.2f公里”,s);} 调试结果:将一张纸折42下的高度为:0.00公里.这个时候老师提问:为什么会出现0.00的情况?请同学们为他指出问题。同学们思考了一会无人作答。这个时候老师提醒:k的值将会很大.结果部分同学作恍然大悟状态,有同学马上举手:老师,变量k的值不能定义为int,应定义为long;问他为什么?他说:int类型的取值范围是:32767,装不下k。老师微笑表扬:方向对了。改好,调试,结果还是0.00公里。这个时候又有同学发言了:老师,不会定义为long都装不下k吧。这个时候老师提问:如果整型数据long都装不下的数据该定义为什么?学生回答:实型float。 改好,调试,Ok,成功!源程序如下 main(){ int i;float s,k=1;for(i=1;i<=42;i++)k=k*2;/* k是纸张的张数 */ s=k*0.1*1.0e-6;/* 将mm转换成km */ printf(“将一张纸折42下的高度为:%.2f公里”,s);} 调试结果:调试结果:将一张纸折42下的高度为:439804.66公里.全班同学的脸上都露出成功的喜悦。可同学们看到结果,表示不太相信,问老师,是不是算错了,有这么高呀。老师作肯定的答复:没错,就有这么高。比地球到月亮的距离(384,401公里)都还要高。这里可以告诫学生,科学不是凭想像,实践出真知。 问题延伸:已知太阳离地球有1.5亿公里,如果理想化的去折纸,最多折多少下有这么高? 学生分组讨论,用什么语句最恰当。得出结论。(用 do while语句)给同学们五分钟,请同学们给出程序并且调试出结果。教师点评学生的程序,指出程序中容易出现错误的地方。源程序如下: main(){ int i,k=1;float s;do { k=k*2;S=k*0.1*1.0e-6;i++;} while(s<=1.5e8);printf(“最多可折%d下有地球到太阳那么高”,i);} 案例反思: 通过这案例教学也给我留下了很多启示: 1、根据C语言的学科特点,和学生的现状,特别是根据学生平时厌理论而乐操作、解决实际问题能力较差的特点,采用案例教学可以充分调动学生学习C语言的兴趣和积极性,使学生处于精神集中的状态,确保学生将知识真正学到手。通过新鲜的案例引领课堂,平时上课精神不集中的学生都认真分析问题了,个别平时打瞌睡的学生精神也集中了。 2、学生编程的信心需要老师去引导和激发。因为C语言程序对于中职学生来讲有些难度,部分学生一看到编程就放弃了,想都不会去想。这个时候老师就要从案例中去引导学生,和学生一起从案例去分析解决这个问题的算法,激发他们编程的尝试。随着程序的成功调试,信心就有了。一个人有了足够的自信,他将有无穷的力量去面对将来的学习和生活。 C语言程序设计教学安排 本课程的任务是结合一般数值计算向学生介绍计算机程序设计的基本知识,使学生掌握C语言的基本内容及程序设计的基本方法与编程技巧,了解进行科学计算的一般思路,培养学生应用计算机解决和处理实际问题的思维方法与基本能力,为进一步学习和应用计算机打下基础。本课程学时总计32学时。 二、课程内容、基本要求与学时分配 ㈠ C语言的基本概念 3学时 1.了解C语言的特点及发展 2.掌握程序的基本结构与书写格式 3.掌握头文件、数据说明、函数的开始和结束标志。 ㈡ 数据类型及其运算 2学时 1.掌握数据类型(基本类型、构造类型、指针类型、空类型)及其定义方法。 2.掌握运算符的种类、运算优先级、结合性。 3.掌握不同类型数据间的转换与运算。 4.掌握表达式类型(赋值表达式、算术表达式、关系表达式、逻辑表达式、条件表达式、逗号表达式)和求值规则。 ㈢ 基本语句 2学时 1.掌握表达式语句、空语句、复合语句。 2.掌握数据的输入/输出和输入/输出函数。 3.掌握go to 语句和语句标号的使用。 ㈣ 选择结构 2学时 1.掌握用if语句实现选择结构。 2.掌握用switch语句实现多分支选择结构。 ㈤ 循环结构 4学时 1.掌握for循环结构。 2.掌握while和do while循环结构。 3.掌握continue、break、return语句。 4.掌握循环的嵌套。 ㈥ 数组的定义和引用 4学时 1.掌握一维数组和多维数组的定义、初始化和引用。 2.掌握字符串与字符数组。 ㈦函数 6学时 1.掌握库函数的正确调用。 2.掌握函数的定义方法。 3.掌握函数的类型和返回值。 4.掌握形式参数与实在参数的区别,参数值的传递。 5.掌握函数的一般调用和嵌套调用,学会递归调用。 6.掌握局部变量和全局变量。 7.掌握变量的存储类型(自动、静态、寄存器、外部),变量的作用域和生存期。 8.了解内部函数和外部函数。 ㈧编译预处理 1学时 1.掌握编译预处理的概念和特点 2.了解带参数的宏定义及其使用,掌握不带参数的宏定义及其使用。 3.掌握“文件包含”的概念和使用。 ㈨指针 8学时 1.掌握指针的概念及指针的定义。 2.掌握指针运算。 3.掌握指向变量、数组、字符串、函数的指针变量。 4.掌握用指针作函数参数。 5.掌握指针数组和指向指针的指针的概念及其定义方法,了解main函数的命令行参数。 ㈩结构与联合 2学时 1.掌握结构和联合类型数据的定义方法。 2.掌握结构和联合类型数据的引用方法。3.掌握指向结构体的指针变量。3.了解用typedef 定义类型的方法。 (十一)文件操作 2学时 1.掌握文件类型指针(file类型指针)。 2.掌握文件的打开与关闭(fopen和fclose函数)。 3.掌握文件的读与写(fprintf和fscanf函数)。 三、说明 本课程的先修课程为《计算机文化基础》和《高等数学》 四、课程使用的教材和主要参考书 使用的教材:《C程序设计》 潭浩强 著 清华大学出版社 主要参考书:《C语言程序设计》 王树义 钱达源 编著 大连理工大学出版社 编游戏 C语言程序设计案例精编.txt让人想念而死,是谋杀的至高境界,就连法医也鉴定不出死因。。。C语言 编游戏案例精编 案例一 贪吃蛇游戏 #define N 200 #include food.x++;while(food.y%10!=0) food.y++; food.yes=0;/*画面上有食物了*/ } if(food.yes==0)/*画面上有食物了就要显示*/ { setcolor(GREEN);rectangle(food.x,food.y,food.x+10,food.y-10);} for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/ { snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];} /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/ switch(snake.direction){ case 1:snake.x[0]+=10;break;case 2: snake.x[0]-=10;break;case 3: snake.y[0]-=10;break;case 4: snake.y[0]+=10;break;} for(i=3;i snake.direction=2;else if(key==DOWN&&snake.direction!=3) snake.direction=4;}/*endwhile(1)*/ } /*游戏结束*/ void GameOver(void){ cleardevice();PrScore();setcolor(RED);settextstyle(0,0,4);outtextxy(200,200,“GAME OVER”);getch();} /*输出成绩*/ void PrScore(void){ char str[10];setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(6);settextstyle(0,0,2);sprintf(str,“score:%d”,score);outtextxy(55,20,str);} /*图形结束*/ void Close(void){ getch();closegraph();} 案例二 计算器 #include x=x0; m=0;} else { x=x+width+width/2; m++;} /*否则,右移到下一个字符位置*/ if(v==LEFT)/*左移箭头时新位置计算*/ if(x<=x0){ x=x0+6*width; m=4;} /*如果移到头,再左移,则移动到最右边字符位置*/ else { x=x-width-width/2; m--;} /*否则,左移到前一个字符位置*/ if(v==UP)/*上移箭头时新位置计算*/ if(y<=y0){ y=y0+4*height+height/2; n=3;} /*如果移到头,再上移,则移动到最下边字符位置*/ else { y=y-height-height/2;n--;} /*否则,移到上边一个字符位置*/ if(v==DOWN)/*下移箭头时新位置计算*/ if(y>=7*height){ y=y0;n=0;} /*如果移到尾,再下移,则移动到最上边字符位置*/ else { y=y+height+height/2; n++;} /*否则,移到下边一个字符位置*/ putimage(x,y,rar,XOR_PUT);/*在新的位置显示光标箭头*/ } c=str1[n*5+m];/*将字符保存到变量c中*/ if(isdigit(c)||c=='.')/*判断是否是数字或小数点*/ { if(flag==-1)/*如果标志为-1,表明为负数*/ { strcpy(str2,”-“);/*将负号连接到字符串中*/ flag=1;} /*将标志值恢复为1*/ sprintf(temp,”%c“,c);/*将字符保存到字符串变量temp中*/ strcat(str2,temp);/*将temp中的字符串连接到str2中*/ setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,str2);/*显示字符串*/ } if(c=='+'){ num1=atof(str2);/*将第一个操作数转换为浮点数*/ strcpy(str2,”“);/*将str2清空*/ act=1;/*做计算加法标志值*/ setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,”0.“);/*显示字符串*/ } if(c=='-'){ if(strcmp(str2,”“)==0)/*如果str2为空,说明是负号,而不是减号*/ flag=-1;/*设置负数标志*/ else { num1=atof(str2);/*将第二个操作数转换为浮点数*/ strcpy(str2,”“);/*将str2清空*/ act=2;/*做计算减法标志值*/ setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);/*画矩形*/ outtextxy(5*width,height,”0.“);/*显示字符串*/ } } if(c=='*'){ num1=atof(str2);/*将第二个操作数转换为浮点数*/ strcpy(str2,”“);/*将str2清空*/ act=3;/*做计算乘法标志值*/ setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,”0.“);/*显示字符串*/ } if(c=='/'){ num1=atof(str2);/*将第二个操作数转换为浮点数*/ strcpy(str2,”“);/*将str2清空*/ act=4;/*做计算除法标志值*/ setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,”0.“);/*显示字符串*/ } if(c=='^'){ num1=atof(str2);/*将第二个操作数转换为浮点数*/ strcpy(str2,”“);/*将str2清空*/ act=5;/*做计算乘方标志值*/ setfillstyle(SOLID_FILL,color+3);/*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2);/*画矩形*/ outtextxy(5*width,height,”0.“);/*显示字符串*/ } if(c=='%'){ num1=atof(str2);/*将第二个操作数转换为浮点数*/ strcpy(str2,”“);/*将str2清空*/ act=6;/*做计算模运算乘方标志值*/ setfillstyle(SOLID_FILL,color+3);/*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2);/*画矩形*/ outtextxy(5*width,height,”0.“);/*显示字符串*/ } if(c=='='){ num2=atof(str2);/*将第二个操作数转换为浮点数*/ switch(act)/*根据运算符号计算*/ { case 1:result=num1+num2;break;/*做加法*/ case 2:result=num1-num2;break;/*做减法*/ case 3:result=num1*num2;break;/*做乘法*/ case 4:result=num1/num2;break;/*做除法*/ case 5:result=pow(num1,num2);break;/*做x的y次方*/ case 6:result=fmod(num1,num2);break;/*做模运算*/ } setfillstyle(SOLID_FILL,color+3);/*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2);/*覆盖结果区*/ sprintf(temp,”%f“,result);/*将结果保存到temp中*/ outtextxy(5*width,height,temp);/*显示结果*/ } if(c=='c'){ num1=0;/*将两个操作数复位0,符号标志为1*/ num2=0;flag=1;strcpy(str2,”“);/*将str2清空*/ setfillstyle(SOLID_FILL,color+3);/*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2);/*覆盖结果区*/ outtextxy(5*width,height,”0.“);/*显示字符串*/ } if(c=='Q')exit(0);/*如果选择了q回车,结束计算程序*/ } putimage(x,y,rar,XOR_PUT);/*在退出之前消去光标箭头*/ return;/*返回*/ } /*窗口函数*/ void mwindow(char *header){ int height;cleardevice(); /* 清除图形屏幕 */ setcolor(MaxColors1);/*设置当前颜色为白色 */ setlinestyle(SOLID_LINE, 0, NORM_WIDTH);/*设置画线方式*/ getviewsettings(&vp);/*将当前视口信息装入vp所指的结构中*/ rectangle(0, 0, vp.right-vp.left, vp.bottom-vp.top);/*画矩形边框*/ } /*设计鼠标图形函数*/ int arrow(){ int size;int raw[]={4,4,4,8,6,8,14,16,16,16,8,6,8,4,4,4};/*定义多边形坐标*/ setfillstyle(SOLID_FILL,2);/*设置填充模式*/ fillpoly(8,raw);/*画出一光标箭头*/ size=imagesize(4,4,16,16);/*测试图象大小*/ rar=malloc(size);/*分配内存区域*/ getimage(4,4,16,16,rar);/*存放光标箭头图象*/ putimage(4,4,rar,XOR_PUT);/*消去光标箭头图象*/ return 0;} /*按键函数*/ int specialkey(void){ int key;while(bioskey(1)==0);/*等待键盘输入*/ key=bioskey(0);/*键盘输入*/ key=key&0xff? key&0xff:key>>8;/*只取特殊键的扫描值,其余为0*/ return(key);/*返回键值*/ } 案例三 黑白棋游戏 #include ”graphics.h“ /*图形系统头文件*/ #define LEFT 0x4b00 /*光标左键值*/ #define RIGHT 0x4d00 /*光标右键值*/ #define DOWN 0x5000 /*光标下键值*/ #define UP 0x4800 /*光标上键值*/ #define ESC 0x011b /* ESC键值*/ #define ENTER 0x1c0d /* 回车键值*/ int a[8][8]={0},key,score1,score2;/*具体分数以及按键与存放棋子的变量*/ char playone[3],playtwo[3];/*两个人的得分转换成字符串输出*/ void playtoplay(void);/*人人对战函数*/ void DrawQp(void);/*画棋盘函数*/ void SetPlayColor(int x);/*设置棋子第一次的颜色*/ void MoveColor(int x,int y);/*恢复原来棋盘状态*/ int QpChange(int x,int y,int z);/*判断棋盘的变化*/ void DoScore(void);/*处理分数*/ void PrintScore(int n);/*输出成绩*/ void playWin(void);/*输出胜利者信息*/ /******主函数*********/ void main(void){ int gd=DETECT,gr;initgraph(&gd,&gr,”c: c“);/*初始化图形系统*/ DrawQp();/*画棋盘*/ playtoplay();/*人人对战*/ getch();closegraph();/*关闭图形系统*/ } void DrawQp()/*画棋盘*/ { int i,j;score1=score2=0;/*棋手一开始得分都为0*/ setbkcolor(BLUE);for(i=100;i<=420;i+=40){ line(100,i,420,i);/*画水平线*/ line(i,100,i,420);/*画垂直线*/ } setcolor(0);/*取消圆周围的一圈东西*/ setfillstyle(SOLID_FILL,15);/*白色实体填充模式*/ fillellipse(500,200,15,15);/*在显示得分的位置画棋*/ setfillstyle(SOLID_FILL,8);/*黑色实体填充模式*/ fillellipse(500,300,15,15);a[3][3]=a[4][4]=1;/*初始两个黑棋*/ a[3][4]=a[4][3]=2;/*初始两个白棋*/ setfillstyle(SOLID_FILL,WHITE);fillellipse(120+3*40,120+3*40,15,15);fillellipse(120+4*40,120+4*40,15,15);setfillstyle(SOLID_FILL,8);fillellipse(120+3*40,120+4*40,15,15);fillellipse(120+4*40,120+3*40,15,15);score1=score2=2;/*有棋后改变分数*/ DoScore();/*输出开始分数*/ } void playtoplay()/*人人对战*/ { int x,y,t=1,i,j,cc=0;while(1)/*换棋手走棋*/ { x=120,y=80;/*每次棋子一开始出来的坐标,x为行坐标,y为列坐标*/ while(1)/*具体一个棋手走棋的过程*/ { PrintScore(1);/*输出棋手1的成绩*/ PrintScore(2);/*输出棋手2的成绩*/ SetPlayColor(t);/*t变量是用来判断棋手所执棋子的颜色*/ fillellipse(x,y,15,15);key=bioskey(0);/*接收按键*/ if(key==ESC)/*跳出游戏*/ break;else if(key==ENTER)/*如果按键确定就可以跳出循环*/ { if(y!=80&&a[(x-120)/40][(y-120)/40]!=1 &&a[(x-120)/40][(y-120)/40]!=2)/*如果落子位置没有棋子*/ { if(t%2==1)/*如果是棋手1移动*/ a[(x-120)/40][(y-120)/40]=1;else/*否则棋手2移动*/ a[(x-120)/40][(y-120)/40]=2;if(!QpChange(x,y,t))/*落子后判断棋盘的变化*/ { a[(x-120)/40][(y-120)/40]=0;/*恢复空格状态*/ cc++;/*开始统计尝试次数*/ if(cc>=64-score1-score2)/*如果尝试超过空格数则停步*/ { MoveColor(x,y); fillellipse(x,y,15,15); break;} else continue;/*如果按键无效*/ } DoScore();/*分数的改变*/ break;/*棋盘变化了,则轮对方走棋*/ } else/*已经有棋子就继续按键*/ continue;} else /*四个方向按键的判断*/ if(key==LEFT&&x>120)/*左方向键*/ { MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);x-=40;fillellipse(x,y,15,15);} else if(key==RIGHT&&x<400&&y>80)/*右方向键*/ { MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);x+=40;fillellipse(x,y,15,15);} else if(key==UP&&y>120)/*上方向键*/ { MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);y-=40;fillellipse(x,y,15,15);} else if(key==DOWN&&y<400)/*下方向键*/ { MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);y+=40;fillellipse(x,y,15,15);} } if(key==ESC)/*结束游戏*/ break;if((score1+score2)==64||score1==0||score2==0)/*格子已经占满或一方棋子为0判断胜负*/ { playWin();/*输出最后结果*/ break;} t=t%2+1;/*一方走后,改变棋子颜色即轮对方走*/ cc=0;/*计数值恢复为0*/ } /*endwhile*/ } void SetPlayColor(int t)/*设置棋子颜色*/ { if(t%2==1)setfillstyle(SOLID_FILL,15);/*白色*/ else setfillstyle(SOLID_FILL,8);/*灰色*/ } void MoveColor(int x,int y)/*走了一步后恢复原来格子的状态*/ { if(y<100)/*如果是从起点出发就恢复蓝色*/ setfillstyle(SOLID_FILL,BLUE);else/*其他情况如果是1就恢复白色棋子,2恢复黑色棋子,或恢复蓝色棋盘*/ switch(a[(x-120)/40][(y-120)/40]){ case 1: setfillstyle(SOLID_FILL,15);break;/*白色*/ case 2: setfillstyle(SOLID_FILL,8);break;/*黑色*/ default: setfillstyle(SOLID_FILL,BLUE);/*蓝色*/ } } int QpChange(int x,int y,int t)/*判断棋盘的变化*/ { int i,j,k,kk,ii,jj,yes;yes=0;i=(x-120)/40;/*计算数组元素的行下标*/ j=(y-120)/40;/*计算数组元素的列下标*/ SetPlayColor(t);/*设置棋子变化的颜色*/ /*开始往8个方向判断变化*/ if(j<6)/*往右边*/ { for(k=j+1;k<8;k++)if(a[i][k]==a[i][j]||a[i][k]==0)/*遇到自己的棋子或空格结束*/ break;if(a[i][k]!=0&&k<8){ for(kk=j+1;kk 案例四 迷宫问题 #include DrawPeople(&x,&y,4);/*右下*/ else if(c=='x'&&map[x+1][y]!=1) DrawPeople(&x,&y,5);/*下*/ else if(c=='z'&&map[x+1][y-1]!=1) DrawPeople(&x,&y,6);/*左下*/ else if(c=='a'&&map[x][y-1]!=1) DrawPeople(&x,&y,7);/*左*/ else if(c=='q'&&map[x-1][y-1]!=1) DrawPeople(&x,&y,8);/*左上*/ } setfillstyle(SOLID_FILL,WHITE);/*消去红色探索物,恢复原迷宫图*/ bar(100+y*15-6,50+x*15-6,100+y*15+6,50+x*15+6);if(x==N-2&&y==N-2)/*人工控制找成功的话*/ yes=1;/*如果成功标志为1*/ } void WayCopy(int(*oldmap)[N],int(*map)[N])/*拷贝迷宫数组 */ { int i,j;for(i=0;i 案例五 扫地雷游戏 #include if(i==9&&j==9)/*右下角格子的统计*/ { if(Mine[9][8].num==1)nNUM++;if(Mine[8][9].num==1)nNUM++;if(Mine[8][8].num==1)nNUM++;} else if(j==0)/*左边第一列格子的统计*/ { if(Mine[i][j+1].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i-1][j].num==1)nNUM++;if(Mine[i-1][j+1].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;} else if(j==9)/*右边第一列格子的统计*/ { if(Mine[i][j-1].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i-1][j].num==1)nNUM++;if(Mine[i-1][j-1].num==1)nNUM++;if(Mine[i+1][j-1].num==1)nNUM++;} else if(i==0)/*第一行格子的统计*/ { if(Mine[i+1][j].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i][j+1].num==1)nNUM++;if(Mine[i+1][j-1].num==1) nNUM++;if(Mine[i+1][j+1].num==1) nNUM++;} else if(i==9)/*最后一行格子的统计*/ { if(Mine[i-1][j].num==1) nNUM++;if(Mine[i][j-1].num==1) nNUM++;if(Mine[i][j+1].num==1) nNUM++;if(Mine[i-1][j-1].num==1) nNUM++;if(Mine[i-1][j+1].num==1) nNUM++;} else/*普通格子的统计*/ { if(Mine[i-1][j].num==1) nNUM++;if(Mine[i-1][j+1].num==1) nNUM++;if(Mine[i][j+1].num==1) nNUM++;if(Mine[i+1][j+1].num==1) nNUM++;if(Mine[i+1][j].num==1) nNUM++;if(Mine[i+1][j-1].num==1) nNUM++;if(Mine[i][j-1].num==1) nNUM++;if(Mine[i-1][j-1].num==1) nNUM++;} return(nNUM);/*把格子周围一共有多少雷数的统计结果返回*/ } int ShowWhite(int i,int j)/*显示无雷区的空白部分*/ { if(Mine[i][j].flag==1||Mine[i][j].num==0)/*如果有红旗或该格处理过就不对该格进行任何判断*/ return;mineNUM--;/*显示过数字或者空格的格子就表示多处理了一个格子,当所有格子都处理过了表示胜利*/ if(Mine[i][j].roundnum==0&&Mine[i][j].num!=1)/*显示空格*/ { DrawEmpty(i,j,1,7);Mine[i][j].num=0;} else if(Mine[i][j].roundnum!=0)/*输出雷数*/ { DrawEmpty(i,j,0,8);sprintf(randmineNUM,”%d“,Mine[i][j].roundnum);setcolor(RED);outtextxy(195+j*20,95+i*20,randmineNUM);Mine[i][j].num=0;/*已经输出雷数的格子用0表示已经用过这个格子*/ return;} /*8个方向递归显示所有的空白格子*/ if(i!=0&&Mine[i-1][j].num!=1)ShowWhite(i-1,j);if(i!=0&&j!=9&&Mine[i-1][j+1].num!=1)ShowWhite(i-1,j+1);if(j!=9&&Mine[i][j+1].num!=1)ShowWhite(i,j+1);if(j!=9&&i!=9&&Mine[i+1][j+1].num!=1)ShowWhite(i+1,j+1);if(i!=9&&Mine[i+1][j].num!=1)ShowWhite(i+1,j);if(i!=9&&j!=0&&Mine[i+1][j-1].num!=1)ShowWhite(i+1,j-1);if(j!=0&&Mine[i][j-1].num!=1)ShowWhite(i,j-1);if(i!=0&&j!=0&&Mine[i-1][j-1].num!=1)ShowWhite(i-1,j-1);} void GamePlay(void)/*游戏过程*/ { int i,j,Num;/*Num用来接收统计函数返回一个格子周围有多少地雷*/ for(i=0;i<10;i++)for(j=0;j<10;j++)Mine[i][j].roundnum=MineStatistics(i,j);/*统计每个格子周围有多少地雷*/ while(!kbhit()){ if(LeftPress())/*鼠标左键盘按下*/ { */ */ MouseGetXY();if(MouseX>280&&MouseX<300&&MouseY>65&&MouseY<85)/*重新来*/ { MouseOff();gameAGAIN=1;break;} if(MouseX>190&&MouseX<390&&MouseY>90&&MouseY<290)/*当前鼠标位置在格子范围内 { j=(MouseX-190)/20;/*x坐标*/ i=(MouseY-90)/20;/*y坐标*/ if(Mine[i][j].flag==1)/*如果格子有红旗则左键无效*/ continue;if(Mine[i][j].num!=0)/*如果格子没有处理过*/ { if(Mine[i][j].num==1)/*鼠标按下的格子是地雷*/ { MouseOff();GameOver();/*游戏失败*/ break;} else/*鼠标按下的格子不是地雷*/ { MouseOff();Num=MineStatistics(i,j);if(Num==0)/*周围没地雷就用递归算法来显示空白格子*/ ShowWhite(i,j);else/*按下格子周围有地雷*/ { sprintf(randmineNUM,”%d“,Num);/*输出当前格子周围的雷数*/ setcolor(RED);outtextxy(195+j*20,95+i*20,randmineNUM);mineNUM--;} MouseOn();Mine[i][j].num=0;/*点过的格子周围雷数的数字变为0表示这个格子已经用过 if(mineNUM<1)/*胜利了*/ { GameWin();break;} } } } } if(RightPress())/*鼠标右键键盘按下*/ { MouseGetXY();if(MouseX>190&&MouseX<390&&MouseY>90&&MouseY<290)/*当前鼠标位置在格子范围内*/ { j=(MouseX-190)/20;/*x坐标*/ i=(MouseY-90)/20;/*y坐标*/ MouseOff();if(Mine[i][j].flag==0&&Mine[i][j].num!=0)/*本来没红旗现在显示红旗*/ { DrawRedflag(i,j);Mine[i][j].flag=1;} else if(Mine[i][j].flag==1)/*有红旗标志再按右键就红旗消失*/ { DrawEmpty(i,j,0,8);Mine[i][j].flag=0;} } MouseOn();sleep(1);} } } 案例六 速算24 #define N 20 #define COL 100 #define ROW 40 #include ”stdio.h“ #include ”time.h“ /*系统时间函数*/ #include ”graphics.h“ /*图形函数*/ #include ”alloc.h“/*动态地址分配函数*/ #include ”stdlib.h“ /*库函数*/ #include ”string.h“ /*字符串函数*/ #include ”ctype.h“ /*字符操作函数*/ char p[4][13]={ {'A','2','3','4','5','6','7','8','9','0','J','Q','K'},/*扑克牌,10用0来表示*/ {'A','2','3','4','5','6','7','8','9','0','J','Q','K'}, {'A','2','3','4','5','6','7','8','9','0','J','Q','K'}, {'A','2','3','4','5','6','7','8','9','0','J','Q','K'}};typedef struct node { int data;struct node *link;}STACK1;/*栈1*/ typedef struct node2 { char data;struct node2 *link;}STACK2;/*栈2*/ void init(void);/*图形驱动*/ void close(void);/*图形关闭*/ void play(void);/*发牌的具体过程*/ void rand1(int j);/*随机发牌函数*/ void change(char *e,char *a);/*中缀变后缀函数*/ int computer(char *s);/*后缀表达式计算函数*/ STACK1 *initstack1(STACK1 *top);/*栈1初始化*/ STACK1 *push(STACK1 *top,int x);/*栈1入栈运算*/ STACK1 *pop(STACK1 *top);/*栈1删除栈顶元素*/ int topx(STACK1 *top);/*栈1读栈顶元素*/ STACK1 *ptop(STACK1 *top,int *x);/*栈1读出栈顶元素值并删除栈顶元素*/ int empty(STACK1 *top);/*判栈1是否为空函数*/ STACK2 *initstack2(STACK2 *top);/*栈2初始化*/ STACK2 *push2(STACK2 *top,char x);/*栈2入栈运算*/ STACK2 *pop2(STACK2 *top);/*栈2删除栈顶元素*/ char topx2(STACK2 *top);/*栈2读栈顶元素*/ STACK2 *ptop2(STACK2 *top,char *x);/*栈2读出栈顶元素值并删除栈顶元素*/ int empty2(STACK2 *top);/*判栈2是否为空函数* int text1(char *s);/*显示文本*/ main(){ char s[N],s1[N],ch;int i,result;int gdriver, gmode;clrscr();/*清屏*/ init();/*初始化函数*/ while(1){ setbkcolor(BLACK);/*设置背景颜色*/ cleardevice();/*清屏*/ play();/*发牌*/ gotoxy(1,15);/*移动光标*/ printf(”--------------------Note-------------------n“);printf(” Please enter express accroding to above four numbern“);/*提示信息*/ printf(” Format as follows:2.*(5.+7.)n“);/*提示输入字符串格式*/ printf(”---------------n“);scanf(”%s%c“,s1,&ch);/*输入字符串压回车键*/ change(s1,s);/*调用change函数将中缀表达式s1转换为后缀表达式s*/ result=computer(s);/*计算后缀表达式的值,返回结果result */ if(result==24)/*如果结果等于24*/ text1(”very good“);/*调用函数text1显示字符串”very good“*/ else text1(”wrong!!“);/*否则函数text1显示字符串”wrong!!“*/ printf(”Continue(y/n)?n“);/*提示信息,是否继续*/ scanf(”%c“,&ch);/*输入一字符*/ if(ch=='n'||ch=='N')/*如果该字符等于n或N*/ break;/*跳出循环,程序结束*/ } /*否则,开始下一轮循环*/ close();return;/*返回*/ } void rand1(int j)/*随机发牌函数*/ { int kind,num;char str[3],n;randomize();while(1)/*循环直到有牌发*/ { kind=random(4);/*花色随机数*/ num=random(13);/*大小随机数*/ if(p[kind][num]!=-1)/*该数未取过*/ { n=p[kind][num];/*取相应位置的扑克牌数*/ p[kind][num]=-1;/*牌发好以后相应位置的元素置-1*/ break;} } switch(kind)/*花式的判断*/ { case 0:setcolor(RED);sprintf(str,”%c“,3);break;/*红桃*/ case 1:setcolor(BLACK);sprintf(str,”%c“,3);break;/*黑桃*/ case 2:setcolor(RED);sprintf(str,”%c“,4);break;/*方片*/ case 3:setcolor(BLACK);sprintf(str,”%c“,5);break;/*草花*/ } settextstyle(0,0,2);outtextxy(COL+j*100-30,ROW+100-46,str);/*显示左上角花色*/ outtextxy(COL+j*100+16,ROW+100+32,str);/*显示右下角花色*/ if(n!='0')/*输出其他牌*/ { settextstyle(0,0,3);sprintf(str,”%c“,n);outtextxy(COL+j*100-5,ROW+100-5,str);/*显示牌的大小*/ } else/*输出10的时候*/ { sprintf(str,”%d“,10);outtextxy(COL+j*100-6,ROW+100-5,str);} } void play(void)/*发牌的具体过程*/ { int j;for(j=0;j<4;j++){ bar(COL+j*100-35,ROW+100-50,COL+j*100+35,ROW+1*100+50);/*画空牌*/ setcolor(BLUE);rectangle(COL+j*100-32,ROW+100-48,COL+j*100+32,ROW+100+48);/*画矩形框*/ rand1(j);/*随机取牌*/ delay(10000);/*延时显示*/ } } void init(void)/*图形驱动*/ { int gd=DETECT,gm;initgraph(&gd,&gm,”c: c“);cleardevice();} void close(void)/*图形关闭*/ { closegraph();} void change(char *e,char *a)/*中缀字符串e转后缀字符串a函数*/ { STACK2 *top=NULL;/* 定义栈顶指针*/ int i,j;char w;i=0;j=0;while(e[i]!=' ')/*当字符串没有结束时*/ { if(isdigit(e[i]))/*如果字符是数字*/ { do{ a[j]=e[i];/*将数字原样拷贝到数组a中*/ i++;/*e数组的下标加1*/ j++;/*a数组的下标加1*/ }while(e[i]!='.');/*直到字符为数字结束符“.”为止*/ a[j]='.';j++;/*将数字结束符“.”拷贝到a数组依然保持结束标记*/ } if(e[i]=='(')/*如果字符是“(”时*/ top=push2(top,e[i]);/*将其压入堆栈*/ if(e[i]==')')/*如果字符是“)”时*/ { top=ptop2(top,&w);/*取出栈顶元素,并从栈顶删除该元素*/ while(w!='(')/*如果字符不是“(”时反复循环*/ { a[j]=w;/*将栈顶元素存入a数组*/ j++;/*下标加1*/ top=ptop2(top,&w);/*取出栈顶元素,并从栈顶删除该元素*/ } } if(e[i]=='+'||e[i]=='-')/*如果字符是加或减号时*/ { if(!empty2(top))/*如栈不为空*/ { w=topx2(top);while(w!='(')/*当栈顶元素不是“(”时反复循环*/ { a[j]=w;j++;/*将栈顶元素存入表达式a中,a的下标加1*/ top=pop2(top);/*删除栈顶元素*/ if(empty2(top))/*如果栈为空*/ break;/*跳出循环*/ else w=topx2(top);/*否则读栈顶元素*/ } } top=push2(top,e[i]);/*将当前e的字符元素压入堆栈*/ } if(e[i]=='*'||e[i]=='/')/*如果字符是乘或除号时*/ { if(!empty2(top))/*如栈不为空*/ { w=topx2(top);/*读栈顶元素存入w*/ while(w=='*'||w=='/')/*当栈顶元素是乘或除时反复循环*/ { a[j]=w;j++;/*将栈顶元素存入字符串a中,a的下标加1*/ top=pop2(top);/*删除栈顶元素*/ if(empty2(top))/*如果栈为空*/ break;/*跳出循环*/ else w=topx2(top);/*否则读栈顶元素*/ } } top=push2(top,e[i]);/*将当前e字符元素压入堆栈*/ } i++;/*e的下标加1*/ } while(!empty2(top))/*当不为空时反复循环*/ top=ptop2(top,&a[j++]);/*将栈顶元素存入数组a中*/ a[j]=' ';/*将字符串结束标记写入最后一个数组元素中构成字符串*/ } int computer(char *s)/* 计算函数*/ { STACK1 *top=NULL;int i,k,num1,num2,result;i=0;while(s[i]!=' ')/*当字符串没有结束时作以下处理*/ { if(isdigit(s[i]))/*判字符是否为数字*/ { k=0;/*k初值为0*/ do{ k=10*k+s[i]-'0';/*将字符连接为十进制数字*/ i++;/*i加1*/ }while(s[i]!='.');/*当字符不为‘.’时重复循环*/ top=push(top,k);/*将生成的数字压入堆栈*/ } if(s[i]=='+')/*如果为'+'号*/ { top=ptop(top,&num2);/*将栈顶元素取出存入num2中*/ top=ptop(top,&num1);/*将栈顶元素取出存入num1中*/ result=num2+num1;/*将num1和num2相加存入result中*/ top=push(top,result);/*将result压入堆栈*/ } if(s[i]=='-')/*如果为'-'号*/ { top=ptop(top,&num2);/*将栈顶元素取出存入num2中*/ top=ptop(top,&num1);/*将栈顶元素取出存入num1中*/ result=num1-num2;/*将num1减去num2结果存入result中*/ top=push(top,result);/*将result压入堆栈*/ } if(s[i]=='*')/*如果为'*'号*/ { top=ptop(top,&num2);/*将栈顶元素取出存入num2中*/ top=ptop(top,&num1);/*将栈顶元素取出存入num1中*/ result=num1*num2;/*将num1与num2相乘结果存入result中*/ top=push(top,result);/*将result压入堆栈*/ } if(s[i]=='/')/*如果为'/'号*/ { top=ptop(top,&num2);/*将栈顶元素取出存入num2中*/ top=ptop(top,&num1);/*将栈顶元素取出存入num1中*/ result=num1/num2;/*将num1除num2结果存入result中* top=push(top,result);/*将result压入堆栈*/ } i++;/*i加1*/ } top=ptop(top,&result);/*最后栈顶元素的值为计算的结果*/ return result;/*返回结果*/ } STACK1 *initstack1(STACK1 *top)/*初始化*/ { top=NULL;/*栈顶指针置为空*/ return top;/*返回栈顶指针*/ } STACK1 *push(STACK1 *top,int x)/*入栈函数*/ { STACK1 *p;/*临时指针类型为STACK1*/ p=(STACK1 *)malloc(sizeof(STACK1));/*申请STACK1大小的空间*/ if(p==NULL)/*如果p为空*/ { printf(”memory is overflown!“);/*显示内存溢出*/ exit(0);/*退出*/ } p->data=x;/*保存值x到新空间*/ p->link=top;/*新结点的后继为当前栈顶指针*/ top=p;/*新的栈顶指针为新插入的结点*/ return top;/*返回栈顶指针*/ } STACK1 *pop(STACK1 *top)/*出栈*/ { STACK1 *q;/*定义临时变量*/ q=top;/*保存当前栈顶指针*/ top=top->link;/*栈顶指针后移*/ free(q);/*释放q*/ return top;/*返回栈顶指针*/ } int topx(STACK1 *top)/*读栈顶元素*/ { if(top==NULL)/*栈是否为空*/ { printf(”Stack is nulln“);/*显示栈为空信息*/ return 0;/*返回整数0*/ } return top->data;/*返回栈顶元素*/ } STACK1 *ptop(STACK1 *top,int *x)/*取栈顶元素,并删除栈顶元素*/ { *x=topx(top);/*读栈顶元素*/ top=pop(top);/*删除栈顶元素*/ return top;/*返回栈顶指针*/ } int empty(STACK1 *top)/*判栈是否为空*/ { if(top==NULL)/*如果为空*/ return 1;/*返回1*/ else return 0;/*否则返回0*/ } STACK2 *initstack2(STACK2 *top)/*初始化*/ { top=NULL;/*栈顶指针置为空*/ return top;/*返回栈顶指针*/ } STACK2 *push2(STACK2 *top,char x)/*入栈函数*/ { STACK2 *p;/*临时指针类型为STACK2*/ p=(STACK2 *)malloc(sizeof(STACK2));/*申请STACK2大小的空间*/ if(p==NULL)/*如果p为空*/ { printf(”memory is overflown!“);/*显示内存溢出*/ exit(0);/*退出*/ } p->data=x;/*保存值x到新空间*/ p->link=top;/*新结点的后继为当前栈顶指针*/ top=p;/*新的栈顶指针为新插入的结点*/ return top;/*返回栈顶指针*/ } STACK2 *pop2(STACK2 *top)/*出栈*/ { STACK2 *q;/*定义临时变量*/ q=top;/*保存当前栈顶指针*/ top=top->link;/*栈顶指针后移*/ free(q);/*释放q*/ return top;/*返回栈顶指针*/ } char topx2(STACK2 *top)/*读栈顶元素*/ { if(top==NULL)/*栈是否为空*/ { printf(”Stack is nulln“);/*显示栈为空信息*/ return '';/*返回空字符*/ } return top->data;/*返回栈顶元素*/ } STACK2 *ptop2(STACK2 *top,char *x)/*取栈顶元素,并删除栈顶元素*/ { *x=topx2(top);/*读栈顶元素*/ top=pop2(top);/*删除栈顶元素*/ return top;/*返回栈顶指针*/ } int empty2(STACK2 *top)/*判栈是否为空*/ { if(top==NULL)/*如果为空*/ return 1;/*返回1*/ else return 0;/*否则返回0*/ } int text1(char *s){ setbkcolor(BLUE);/*设置背景颜色为蓝色*/ cleardevice();/*清除屏幕*/ setcolor(12);/*设置文本颜色为淡红色*/ settextstyle(1, 0, 8);/*三重笔划字体, 放大8倍*/ outtextxy(120, 120, s);/*输出字符串s*/ setusercharsize(2, 1, 4, 1);/*水平放大2倍, 垂直放大4倍*/ setcolor(15);/*设置文本颜色为*白色/ settextstyle(3, 0, 5);/*无衬字笔划, 放大5倍*/ outtextxy(220, 220, s);/*输出字符串s*/ getch();/*键盘输入任一字符*/ return;/*返回*/ } 案例七 数据结构CAI系统 案例八 进程调度 #include ”stdio.h“ #include ”stdlib.h“ #include ”string.h“ typedef struct node { char name[10];/*进程标识符*/ int prio;/*进程优先数*/ int round;/*进程时间轮转时间片*/ int cputime;/*进程占用CPU时间*/ int needtime;/*进程到完成还要的时间*/ int count;/*计数器*/ char state;/*进程的状态*/ struct node *next;/*链指针*/ }PCB;PCB *finish,*ready,*tail,*run;/*队列指针*/ int N;/*进程数*/ /*将就绪队列中的第一个进程投入运行*/ firstin(){ run=ready;/*就绪队列头指针赋值给运行头指针*/ run->state='R';/*进程状态变为运行态*/ ready=ready->next;/*就绪对列头指针后移到下一进程*/ } /*标题输出函数*/ void prt1(char a){ if(toupper(a)=='P')/*优先数法*/ printf(” name cputime needtime priority staten“);else printf(” name cputime needtime count round staten“);} /*进程PCB输出*/ void prt2(char a,PCB *q){ if(toupper(a)=='P')/*优先数法的输出*/ printf(” %-10s%-10d%-10d%-10d %cn“,q->name, q->cputime,q->needtime,q->prio,q->state);else/*轮转法的输出*/ printf(” %-10s%-10d%-10d%-10d%-10d %-cn“,q->name, q->cputime,q->needtime,q->count,q->round,q->state);} /*输出函数*/ void prt(char algo){ PCB *p;prt1(algo);/*输出标题*/ if(run!=NULL)/*如果运行指针不空*/ prt2(algo,run);/*输出当前正在运行的PCB*/ p=ready;/*输出就绪队列PCB*/ while(p!=NULL){ prt2(algo,p);p=p->next;} p=finish;/*输出完成队列的PCB*/ while(p!=NULL){ prt2(algo,p);p=p->next;} getch();/*压任意键继续*/ } /*优先数的插入算法*/ insert1(PCB *q){ PCB *p1,*s,*r;int b;s=q;/*待插入的PCB指针*/ p1=ready;/*就绪队列头指针*/ r=p1;/*r做p1的前驱指针*/ b=1;while((p1!=NULL)&&b)/*根据优先数确定插入位置*/ if(p1->prio>=s->prio){ r=p1;p1=p1->next;} else b=0;if(r!=p1)/*如果条件成立说明插入在r与p1之间*/ { r->next=s;s->next=p1;} else { s->next=p1;/*否则插入在就绪队列的头*/ ready=s;} } /*轮转法插入函数*/ insert2(PCB *p2){ tail->next=p2;/*将新的PCB插入在当前就绪队列的尾*/ tail=p2;p2->next=NULL;} /*优先数创建初始PCB信息*/ void create1(char alg){ PCB *p;int i,time;char na[10];ready=NULL;/*就绪队列头指针*/ finish=NULL;/*完成队列头指针*/ run=NULL;/*运行队列指针*/ printf(”Enter name and time of processn“);/*输入进程标识和所需时间创建PCB*/ for(i=1;i<=N;i++){ p=malloc(sizeof(PCB));scanf(”%s“,na);scanf(”%d“,&time);strcpy(p->name,na);p->cputime=0;p->needtime=time;p->state='w';p->prio=50-time;if(ready!=NULL)/*就绪队列不空调用插入函数插入*/ insert1(p);else { p->next=ready;/*创建就绪队列的第一个PCB*/ ready=p;} } clrscr();printf(” output of priority:n“);printf(”************************************************n“);prt(alg);/*输出进程PCB信息*/ run=ready;/*将就绪队列的第一个进程投入运行*/ ready=ready->next;run->state='R';} /*轮转法创建进程PCB*/ void create2(char alg){ PCB *p;int i,time;char na[10];ready=NULL;finish=NULL;run=NULL;printf(”Enter name and time of round processn“);for(i=1;i<=N;i++){ p=malloc(sizeof(PCB));scanf(”%s“,na);scanf(”%d“,&time);strcpy(p->name,na);p->cputime=0;p->needtime=time;p->count=0;/*计数器*/ p->state='w';p->round=2;/*时间片*/ if(ready!=NULL)insert2(p);else { p->next=ready;ready=p;tail=p;} } clrscr();printf(” output of roundn“);printf(”************************************************n");prt(alg);/*输出进程PCB信息*/ run=ready;/*将就绪队列的第一个进程投入运行*/ ready=ready->next;run->state='R';} /*优先数调度算法*/ priority(char alg){ while(run!=NULL)/*当运行队列不空时,有进程正在运行*/ { run->cputime=run->cputime+1;run->needtime=run->needtime-1;run->prio=run->prio-3;/*每运行一次优先数降低3个单位*/ if(run->needtime==0)/*如所需时间为0将其插入完成队列*/ { run->next=finish;finish=run;run->state='F';/*置状态为完成态*/ run=NULL;/*运行队列头指针为空*/ if(ready!=NULL)/*如就绪队列不空*/ firstin();/*将就绪对列的第一个进程投入运行*/ } else /*没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列*/ if((ready!=NULL)&&(run->prio 《C语言程序设计》教学的几点体会 江西司法警官职业学院欧阳群 摘要:随着科学技术的发展,计算机已普及到各行各业,深入到各级层次,越来越多高校把《C 语言程序设计》作为使用学习编程的入门语言,《C语言程序设计》课程已成为当近计算机教育的一门必修基础课。因而,搞好该门课程的教学具有非常重要而深远的意义。 关键字:C 语言程序设计 教学 算法引言 学习计算机程序设计语言是提高人们计算机知识水平的关键步骤。C语言作为当今最流行的程序设计语言之一,不但成为计算机专业的必修课。而且也越来越多的成为非计算机专业的学习课程。C语言简洁,紧凑使用起来方便,灵活,运算符和数据结构丰富,可移植性好,硬件控制能力高,表达和运算能力强。其运算速度也优于C++。但同时,C语言又是一门学习起来难度较大的语言,同学们反映,学习过程中经常会出现一些问题,对语句没有直观的理解,而是死记硬背,缺乏对一些算法的清楚认识以及缺少对运算符等语法方面的理解,造成编写程序时无法理清楚解题思路,无从入手,在程序调试的过程中不认真分析出错原因,面对枯燥的程序题,便失去了积极性。鉴于上面一些问题,下面笔者从激发学生的学习兴趣、培养学生对方法的理解、如何让学生 处理好语法与算法的关系、加强实践操作等几方面谈谈我的教学体会: 2、在教学过程中要激发学生的学习兴趣 有句话说的好“兴趣与爱好是最好的老师”。为了使学生能尽快地掌握计算机知识,进入计算机的应用领域,在课程讲授过程中,要特别注意培养学生的学习兴趣。很多学生和我说过,他们学习计算机就是从玩游戏开始的。学生们刚接触计算机时都会感到新奇、好玩。这还不能说是兴趣,只是一种好奇。随着课程的不断深入,概念、语法规则、算法等知识的学习加大学习难度,使一部分(甚至是大部分)学生对课程学习产生厌倦情趣。为了把学生对计算机程序设计初期产生的好奇心转变为学习兴趣,授课时我们可以把对定义和规则的讲解与具体问题结合起来,努力把枯燥无味的“语言”讲的生动、活泼。在第一节课上,我们可以给同学展示一些已经做好的程序,让同学们对C能做出些什么程序有一定的了解,并把C和学生曾经学过的其他课程联系起来。例如数学中的很多问题,是C语言初期学习算法时比较好的引例。在课程的进行中,引导学生学一种算法,就尝试在同行课程中应用。我们还可以经常介绍一些趣味性算例,如: “菲波纳契兔子问题”、“水仙花数”、“竞赛记分”等,培养学生的学习兴趣,让大家积极主动、自觉独立地获取知识,打好学习程序设计语言的基础。整个教学过程中应该把解题思路、方法和步骤(即“算法”)当作授课的重点,从而让学生明白如何分析并解决实际问题,逐渐培养学生进行程序设计的正确思维模式。 2、在教学过程中要加强学生对程序的理解 对于一门艺术性的语言,它的价值便是它的实用性和美感。众所周知,英语的美感在于它的发音、而汉语则在于它的象形,它们给人的一种直观感觉就是美。C语言作为一门计算机语言,它的美又在哪里呢?那便是它的可持续性,正确性与实用性,也就是说一个程序我们一眼看上去就能理解它想表达的是什么,所以在教学过程,如何让学生理解好程序,成了入门最重要的一步,例如:我们在学习两个数交换时: main() {int a=1,b=2.c; c=a; a=b; b=c;} 如果只是看c=a,a=b,b=c是相当难理解的,但是,若是加以联想,我有两杯水,要将杯中的水相互交换,便要引入一个空杯了,而这个空杯子正是C,这样问题被轻而易举地理解了,又如,我们在学习排序方法时,由于算法理解起来比较复杂,此时我们要联系生活中的例子,以上体育课中排 队为例按个子高低从小到大排列,并结合程序考虑该如何移动位臵。通过与生活实际相结合,理解相对枯燥难懂的程序算法,放弃传统的死记硬背的方法,无疑可以使原本吃力的学习得到一定的缓解。 3、在教学过程中要让学生正确处理语法与算法的关系。教学中对程序课程教学的一项基本目的是要让学生掌握设计程序的思路并对待处理实现的任务能用计算机语言编写出程序。要让学生完成程序,如何处理算法与语法之间的关系显得犹为重要。算法是程序的核心与灵魂,是程序精华的体现,语法仅仅是一种程序工具,我们在教学过程中不应把重点放在语法规则的教学上,语法是重要,不掌握语法规则就无法编写出正确的程序,但是只学会语法,甚至能把语法背得滚瓜烂熟,也不可能编写好程序。我们应该把重点放在解题思路上,即算法的讲解及算法优化上,对于一个经典的算法,需要通过大量的例题进行学习。在学习开始时没必要在语法细节上死背死抠,毕竟让学生能编出程序才是最重要。一些语法细节是需要通过长期实践才能掌握的。在学生对算法能够较好理解后,再层层深入,让学生去加强对语法的理解。 4、在教学过程中要突出实践操作的重要性 程序设计课程实践性很强,同学在学习过程中只听不练根本达不到预期的学习效课,每次上机前,都要根据教学计 划布臵与理论教学配套的实践作业,让学生明确上机任务,编写好上机调试的程序,使学生在每次上机实习中有收获,加强对理论的理解。我们可以在机房中设立教师机,让学生在教师机上建立以学号和姓名为文件名的文件夹,以后每节课作业都存入其中,课程结束后按作业的多少、优劣来评定实习成绩。针对程序设计中的一些操作难点,可以让学生分组讨论并集中演示,这可以起到事半功倍的效果。课程结束前我们把教师机中学生作业完成情况及所学的内容作一个分析,并进行有针对性的讲解,前后联系起来,使学生对课程内容能够融汇贯通。我们要让学生用积极的思维解决出现问题,程序报错不能运行时,认真检查核对语法错误;程序能运行却得不到正确的结果时,认真检查核对算法的疏漏,使学生知道可能往往程序中一个小小标点或者字母的失误,都可能导致整个程序出现问题。 5、结束语 在对学生进行C语言教学时,除了采取以上措施外,笔者认为由于该课程涉及内容太多,在学时较少的情况下,可以对一些应用性教差及教难的问题适当带过,如果,过分强调那些难点问题,必然影响学生对基本知识的理解,并且也会加大学生学习负担。学生掌握好程序设计中最基本、最常用的部分后已经可以解决大多数的问题。在学生熟练地掌握了基本知识后再去学习较难的部分也会使难点问题简单很 多。“授之鱼、不如授之以渔”,在教学中除了要加强学生对知识的理论学习外,最重要的是培养学生从计算机的角度去考虑如何解决问题、培养学生良好的思维习惯。 参考文献 [1]谭浩强.C语言程序设计.清华大学出版社, 2002 [2] 石爱容, C语言程序设计课程教学探析.警官教育论坛,2006年第2期 [3] 吴丽丽.论职业技术教育中《C语言程序设计》的教学.科技信息(学术版).2006第9期 [4] 张海玉.C语言程序设计教学方法探析.山西财政税务专科学校学报.2006年 第8卷 第1期 [5] 孙锋.C 语言程序设计教学的几点体会.教育与培训.2006 第7期 作者简介: 欧阳群, 女, 江西司法警官职业学院司法信息系,助理讲师第二篇:《C语言循环程序设计for语句》教学案例
第三篇:C语言程序设计教学安排
第四篇:编游戏 C语言程序设计案例精编
第五篇:《C语言程序设计》教学的几点体会