版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
程序的重复之美—循环结构程序设计C语言程序设计第五章本章目录01.while循环02.do…while循环03.for循环04.多重循环05.break语句和continue语句06.趣味实例5.1while循环语句学习while循环的语法、执行流程和使用方法while循环的语法与执行流程书写格式
while(表达式){语句序列(循环体)//需包含改变条件的语句}执行流程解析1.条件判断:计算表达式,若为假(0)直接跳出循环。2.执行循环体:若条件为真(非0),执行循环体。3.循环往复:执行完毕后,返回步骤1再次判断条件。关键特点与避坑指南1.先判断后执行,初始条件为假则不执行。2.务必包含改变条件的语句(如i++),防止死循环。while循环的使用注意事项1)循环前,必须给循环变量赋初值。2)若循环体包含一条以上的语句,应以复合语句形式出现。3)循环体中,必须有改变循环变量值的语句(使循环趋向结束的语句),否则会陷入无限循环。4)while循环的特点是先判断条件表达式,后执行循环体语句,因此循环体有可能一次也不执行。5)无限循环:while(1)循环体;6)循环体可以为空。例:while((c=getchar())!='A');实例体验:例
5-1
观察下列程序。1)找出循环结构的三要素:循环体、循环变量及循环结束条件。2)写出该程序完成的功能。程序代码#include<stdio.h>main(){inti=3;intsum=0;while(i<100){sum=sum+i;i+=3;}printf("sum=%d\n",sum);}实例体验:问题描述:毫厘与千里一年365天,能力值的基数记为1。当好好学习一天时,能力值相比前一天提高1%;当没有好好学习时,能力值相比前一天下降1%,每天努力学习和每天放任自流,一年下来能力值相差多少呢?例5-2
编程实现计算能力值。实例体验:
实例体验:程序代码:#include<stdio.h>main(){intday=1;floatpositive=1,negative=1;while(day<=365){day++;positive=positive*1.01;negative=negative*0.99;printf("每天进步一点点,一年后能力值为:%.2f\n",positive);printf("每天退步一点点,一年后能力值为:%,2f\n",negative);}}5.2do…while循环语句学习do-while循环的语法、执行流程,并与while循环进行比较do…while循环的语法与执行流程书写格式do{循环体}while(条件表达式);//注意末尾分号核心特点与注意事项执行逻辑:先执行循环体,后判断条件表达式的值。保底执行:无论初始条件是否为真,循环体至少执行一次。语法规范:while表达式末尾必须有分号;。执行流程图解流程简述:执行循环体→判断条件真假→为真则重复执行,为假则跳出循环。do…while循环的使用注意事项do…while循环与while循环类似,使用do…while循环时要注意的事项:1)使用注意事项同while循环。2)while语句后的分号必须有,不要漏掉。循环体只有一个语句,也不能省略花括号。实例体验:例5-3
使用
do…while
语句计算
1+2+3+…+100。分析:
根据题意,结合顺序结构的设计思路,该题为累加求和的问题,即s=1+2+3+…+100。s=0s=s+1s=s+2s=s+3…程序代码#include<stdio.h>main(){inti=1,s=0;do{s=s+i;i++;}while(i<=100);//循环结束条件printf("s=%d\n",s);}可写成通项式:s=s+iliuchengtu流程图实例体验:问题描述:网贷的危害大学生王林看上一款8000多元的手机,因家庭暂时难以承担这笔费用,便动了网络贷款的念头。某“校园贷”宣称无需抵押,日利率仅千分之五(贷款1000元每日利息5元)。王林觉得贷10000元,日息50元,自己节省生活开支就能很快还清,于是签订了12个月的还款协议。事情真会如王林所想吗?12个月后王林需要偿还多少金额?例
5-4
编程计算网贷利息。实例体验:分析:根据题意,第一天还息10000元的0.5%为50元,第二天还息为(10000+50)元的0.5%,解题思路同例题5-2。流程图(见图5-5)。实例体验:程序代码:#include<stdio.h>main(){floatmoney=10000;li=0.005;intday=0;do{day++;money=money*(1+li);}while(day<365);printf("12个月后本金加利息共计%9.2lf\n",money);}5.3for循环语句学习for循环的语法、执行流程,掌握其在计数循环中的应用for循环的语法与执行流程书写格式for(表达式1;表达式2;表达式3){循环体;//执行任务}表达式1(初始化):只执行一次,设置循环起点。表达式2(条件判断):每次循环前判断,决定是否继续。表达式3(更新变量):循环体执行后更新,迈向终点。特点:结构紧凑,可读性高,是计数循环的首选。表达式1:初始化变量,进入循环准备状态表达式2:判断条件真假,假则跳出,真则执行循环体表达式3:更新变量,返回步骤2再次判断,形成闭环参数说明和特点for循环使用注意事项1)表达式1、表达式2和表达式3之间是用分号“;”隔开的。表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式。表达式2一般是关系表达式或逻辑表达式,也可以是数值表达式或字符表达式,只要其值为非零,就执行循环体。2)“表达式1”可以省略,但表达式1后的分号不能省略。例如:for(;i<=100;i++)。由于省略了表达式1,没有对循环变量赋初值,因此,为了能正常执行循环,应在for语句之前给循环变量赋以初值。3)表达式2也可以省略,即不设置和检查循环的条件。此时循环无终止地进行下去,也就是认为表达式2始终为真。4)表达式3也可以省略,但此时程序设计者应另外设法保证循环能正常结束。5)for语句的循环体可为空语句。此时可把本来要在循环体内处理的内容放在表达式3中,也可以写成“for(i=1;i<=100;i++);”,说明循环体全空。实例体验:例
5-5
从键盘输入
10
个整数,求其和。分析:
10个整数求和类似1+2+3+…+100的累加计算。此处被加项的数值不是规律的数字,因此不能用例5-2中的循环变量充当被加项,此处可用另一个变量替代。同时依次给该变量赋值,加入总和中即可。程序代码#include<stdio.h>main(){intsum,num,i;printf("从键盘上输入10个整数:\n");sum=0;for(i=1;i<=10;i++){scanf("%d",&num);sum=sum+num;}printf("这10个整数的和为:%d\n",sum);}liuchengtu流程图实例体验:问题描述:爱护树木,人人有责我们都知道,树木具有吸收二氧化碳并释放氧气的功能,能减少温室气体,缓解热效应。不同种类的树木吸收二氧化碳量存在差异,假设一棵树每年能吸收22kg的二氧化碳,那100棵树每年总共吸收多少二氧化碳呢?例
5-6
编程计算大树每年吸收多少二氧化碳。实例体验:分析:本题计算较为简单,可用加法,100棵树的吸收量是100个22相加,根据例5-5的编程思路,用for循环很容易实现。当然也可以用乘法,就是100*22,用顺序结构编程也可实现,这里我们用循环,再次体验for循环的魅力。流程图(见图5-8)实例体验:程序代码:#include<stdio.h>intmain(){inttrees=100;//假设有100棵树,此处用变量,便于修改//不同数量值inti,sum=0,CO2=22;//每棵树每年吸收22kg二氧化碳for(i=1;i<=trees;i++){sum=sum+CO2;}printf("100棵树每年总共吸收二氧化碳:%dkg\n",sum);}5.4多重循环理解循环嵌套的概念和执行流程多重循环核心定义在一个循环的循环体中包含另一个完整循环。外层循环控制大流程,内层循环处理细节。执行过程外层循环每执行一次,内层循环必须完整执行一遍(从条件成立到不成立)。常见组合形式支持多种组合:while嵌套while、for嵌套for、while与for相互嵌套。关键注意事项内循环全包含在外循环里;内层与外层循环变量严禁重名;嵌套层数不宜过深,影响可读性。实例体验:例5-8打印九九乘法表分析双重循环结构外层循环(i)控制行数(1-9),内层循环(j)控制列数(1-i),确保列数不超过行数。格式化输出使用printf格式化字符串,设置宽度对齐(如%-4d),保证表格整齐美观。换行控制内层循环结束后,执行printf("\n")换行,开始打印下一行数据。C语言实现代码#include<stdio.h>main(){inti,j;//外层循环控制行数for(i=1;i<=9;i++){//内层循环控制列数for(j=1;j<=i;j++){printf("%d*%d=%-4d",j,i,j*i);}printf("\n");//换行}}5.5break和continue语句学习如何使用break和continue语句控制循环的执行流程break和continue语句break语句:结束整个循环功能:跳出并结束当前所在的循环结构或switch语句。机制:执行时立即跳出包含它的最内层循环,循环终止,开始执行后续代码。continue语句:结束本次循环功能:跳过当前循环的剩余语句,直接开始下一次循环的条件判断。机制:不执行后续语句,直接跳转到循环的更新或条件判断部分。实例体验:例5-9
问题描述:某次班级开展“继承革命传统传承红色基因”主题班会,设置答题活动,其中一个问题为:长征的年份是哪一年?每人5次回答机会。请根据要求编写程序。分析:for语句指定执行循环体5次。每次循环中,输入一个答案,并将答案与正确答案比对。设置了if语句,若输入答案与正确答案一致就执行break语句,流程跳出当前循环,提前结束循环。实例体验:程序代码:#include<stdio.h>main(){inti;intsuccess=0;//初始成功次数为0printf("请回答问题:长征的年份是哪一年?你将有5次机会回答这个问题。\n");for(i=1;i<=5;i++){printf("尝试次数%d:长征的年份是哪一年?\n",i);scanf("%d",&success);if(success==1934){printf("恭喜你,正确答对了长征的年份!\n");break;//当用户正确回答时,跳出循环}else{if(i==5&&success!=1934){printf("很遗憾,你没有在指定的次数内答对长征的年份,请继续努力。\n");break;//5次均答错,跳出当前循环}//如果用户回答错误,给予提示并继续尝试printf("不正确,请再尝试一次。记住,坚持就是胜利!\n");}}}5.6趣味实例—猴子吃桃编程通过具体实例,学习如何编写循环结构的C语言程序趣味实例实训目的1.了解循环程序的基本结构。2.熟悉while语句、do…while语句、for语句的结构和实现循环的编程方法。3.了解循环语句的运行顺序及编程中的注意事项。实训内容1.基础训练猴子摘下若干桃子,第1天吃了4个;第2天比第1天多吃了一个,依次类推,
一共吃了10天,把桃子都吃完了。1)猴子一共摘了多少个桃子?2)将猴子每天吃的桃子数量,用图形的方式表示出来。2.提升训练猴子在第1天摘下若干桃子,当即吃了一半,还没吃饱,又多吃了一个;第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的桃子的一半零一个。到第10天早上想再吃时,发现只剩下一个桃子了。1)求第1天共摘了多少个桃子?2)将猴子每天吃的桃子数量,用图形的方式表示出来。实训流程知识准备掌握循环语句基础训练1)内容分析:猴子吃桃是依次递增的,该计算类似累加。2)编程分工:独立或小组合作(小组协作分析交流)。3)编程、上机验证。编程提示分析时,先明确数学解题思路,再将其用C语言的表示方法表示出来,画出整个程序的流程图,帮助分析程序的需求及走向。编程时,根据流程图写出对应的语句即可。实训流程提升训练1)内容分析:该题的数学解析C语言解析假设每天的桃为x个假设每天的桃为x个第10天为:x=1第10天为:x=1第9天为:2(x+1)第9天为:x=2*(x+1)第8天为:2(2(x+1)+1)第8天为:x=2*(x+1)打印图形,模仿前面编程,找准每天的数量即可。2)编程分工:独立或小组合作。3)编程、上机验证。本章小结:做事要有序—数组的应用C语言程序设计第六章本章目录01.一维数组的定义和应用02.二维数组的定义和应用03.字符数组的定义和应用04.趣味实例6.1一维数组的定义和应用存储一组相同类型的数据一维数组的定义一般形式类型说明符数组名[常量表达式];类型说明符:指定元素数据类型(如int,float,char)。数组名:遵循变量命名规则,代表数组的标识。常量表达式:用方括号括起,指定数组长度(元素个数),必须是常量。示例inta[6];//整型数组a,含6个元素floatb[6],c[8];//浮点型数组b,含6个元素;浮点型数组c,有8个元素。注意事项1)数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。2)数组名的书写规则应符合标识符的书写规定。3)数组名不能与其他变量名相同。4)方括号中常量表达式表示数组元素的个数,其下标从0开始计算。结构、参数说明一维数组的引用一般形式
数组名[下标];例如:score[0]避坑指南:下标越界(补充)C语言不检查下标越界。若使用score[10](数组长度为10),程序可能编译通过但运行时崩溃。
数组的主要目的是处理批量数据,数组元素是组成数组的基本单元。数组元素也是一种变量,其标识方法为数组名后跟一个下标。下标表示元素在数组中的顺序号。其中下标只能为整型常量或整型表达式。如为小数时,C编译将自动取整。以下都是合法的数组元素:a[10]a[2+8]a[2*5]起始值:从0开始,而非1范围:长度为n的数组,合法下标为0~n-1一维数组的初始化
数组的初始化实际上是对数组元素的初始化。给数组赋值的方法除了用赋值语句对数组元素逐个赋值外,还可采用初始化赋值和动态赋值的方法。
数组初始化赋值指在数组定义时给数组元素赋予初值。这种赋值方式简洁高效,能一次性为多个元素赋初值,避免了后续逐个赋值的繁琐操作。初始化赋值的一般形式为:
类型说明符数组名[常量表达式]={值,值,……,值};其中,在{}中的各数据值即为各元素的初值,各值之间用逗号间隔。例如:inta[10]={0,1,2,3,4,5,6,7,8,9};相当于:a[0]=0、a[1]=1、…、a[9]=9。一维数组的初始化C语言对数组的初始化赋值还有以下几点规定:1)可以只给部分元素赋初值。当{}中值的个数少于元素个数时,只给前面部分元素赋值。例如“inta[10]={0,1,2,3,4};”,表示只给a[0]~a[4]5个元素赋值,而后5个元素自动赋0值。2)只能给元素逐个赋值,不能给数组整体赋值。例如:给5个元素全部赋1值只能写为:inta[5]={1,1,1,1,1};而不能写为:inta[5]={1};3)初始化省略长度。如给全部元素赋值,则在数组说明中,可以不给出数组元素的个数。例如“inta[5]={1,2,3,4,5};”可写为:inta[]={1,2,3,4,5};4)数组动态赋值是指在程序执行过程中,用循环语句配合scanf()函数对数组元素逐个赋值。实例体验例6-1:用for循环为数组赋值并逆序输出#include<stdio.h>main(){inti,a[10];for(i=0;i<=9;i++)
a[i]=i;for(i=9;i>=0;i--)
printf("%d",a[i]);}例6-2:垃圾分类统计与宣传问题描述:垃圾分类统计随着城市化进程的加快,垃圾处理已成为不容忽视的社会问题。垃圾分类不仅有助于资源回收利用,还能减少环境污染,是实现可持续发展的重要举措。近年来,我国大力推进垃圾分类政策,倡导全民参与。某社区积极响应政策,将垃圾分为四类:可回收垃圾、有害垃圾、厨余垃圾和其他垃圾。为深入了解居民的垃圾分类情况,社区计划统计一周内每天各类垃圾的投放量。一维数组应用实例例6-2:垃圾分类统计与宣传for(i=0;i<7;i++){printf("第%d天:",i+1);scanf("%d%d%d%d",&recyclable[i],&hazardous[i],&kitchen[i],&other[i]);totalRecyclable+=recyclable[i];totalHazardous+=hazardous[i];totalKitchen+=kitchen[i];totalOther+=other[i]; }printf("\n一周内各类垃圾的总投放量:\n");//输出一周各类垃圾的总投放量printf("可回收垃圾:%dkg\n",totalRecyclable);例6-2:垃圾分类统计与宣传printf("有害垃圾:%dkg\n",totalHazardous);printf("厨余垃圾:%dkg\n",totalKitchen);printf("其他垃圾:%dkg\n",totalOther);//比较一周可回收垃圾与其他垃圾的占比if(totalRecyclable>totalOther){printf("\n恭喜!可回收垃圾占比高于其他垃圾,环保工作做得很好!\n");}else{printf("\n注意!可回收垃圾占比低于其他垃圾,需要加强垃圾分类意识。\n");}printf("\n垃圾分类,人人有责!保护环境,从我做起!\n");}6.2二维数组的定义和应用存储表格形式的数据二维数组的定义一般形式类型说明符数组名[常量表达式1][常量表达式2];常量表达式1(行数):定义二维数组包含的一维数组个数。(第一维下标长度)常量表达式2(列数):定义每个一维数组元素包含的变量个数。(第二维下标长度)示例inta[3][4];//3行4列,共12个元素二维数组本质上是“数组的数组”。a[3][4]可视为包含3个元素的一维数组。其中每个元素(a[0],a[1],a[2])又是一个包含4个整型元素的一维数组。通常可用矩阵表示如下:参数说明二维数组的引用二维数组的元素也称为双下标变量,二维数组元素的引用方式为:数组名[行下标][列下标];其中,下标应为整型常量或整型表达式。例如“a[3][4];”,表示数组a有3行4列的元素。内存存储机制采用“按行优先顺序”连续存储。存储逻辑:先存第一行所有元素,再存第二行,依此类推。下标从0开始。二维数组的初始化方式1:按行全部初始化--分段初始化inta[2][3]={{1,2,3},{4,5,6}};最清晰的方式,外层大括号内的每一对内层大括号对应一行的初始化值,可读性强。方式3:按行全部初始化--连续初始化inta[2][3]={1,2,3,4,5,6};将所有元素的值按行的顺序依次列出来,效果与按行分段初始化完全相同。方式2:按行部分初始化inta[2][3]={{1,2},{4}};只对部分元素赋值,未赋值的元素自动初始化为0。例如:120/400。方式3:省略行长度(列不可省)inta[][3]={1,2,3,4,5};系统根据数据个数和列长度自动计算行数。如示例中5个数据,列数3,则行数为2。实例体验:例6-3一个学习小组有5个人,每个人有3门课的考试成绩,求全组分科的平均成绩和各科总平均成绩。分
析:可设一个二维数组a[3][5]存放5个人3门课的成绩。再设一个一维数组v[3]存放所求的各分科平均成绩,设变量average为全组各科总平均成绩。
程序代码#include<stdio.h>main(){inti,j;floats=0.0,average,v[3],a[3][5];printf("inputscore\n");for(i=0;i<3;i++){for(j=0;j<5;j++){scanf("%f",&a[i][j]);s=s+a[i][j];}程序代码v[i]=s/5;s=0;}average=(v[0]+v[1]+v[2])/3;printf("Math_average:%.2f\nChina_average:%.2f\nEnglish_average:%.2f\n",v[0],v[1],v[2]);printf("total_average:%.2f\n",average);}实例体验:问题描述:学生课堂表现评分统计为深入了解学生的学习态度和课堂表现,某班级开展课堂表现评分工作。评分包括三个方面:积极参与、认真听讲和作业完成情况。通过统计每个学生的综合评分,教师可以更好地了解学生的学习情况,并给予针对性的指导。例6-4学生课堂表现评分统计。分析:本例可借助一个二维数组来存储每个学生的3个评分项(积极参与、认真听讲和作业完成情况),并通过循环一次性输入这些数据。随后,计算每个学生的综合评分(3个评分项的平均值)。最后,把每个学生的综合评分输出显示。实例体验程序代码:#include<stdio.h>main(){intstudents=5;//假设有5名学生intcriteria=3;//3个评分项:积极参与、认真听讲、作业完成floatscores[students][criteria];//二维数组存储每个学生的评分floattotalScore,averageScore;//输入每个学生的课堂表现评分
printf("请输入每个学生的课堂表现评分(积极参与、认真听讲、作业完成,用空格分隔):\n");for(inti=0;i<students;i++){
printf("学生%d:",i+1);
for(intj=0;j<criteria;j++){scanf("%f",&scores[i][j]);}}//计算并输出每个学生的综合评分
printf("\n每个学生的综合评分:\n");for(inti=0;i<students;i++){totalScore=0;for(intj=0;j<criteria;j++){totalScore+=scores[i][j];}averageScore=totalScore/criteria;printf("学生%d的综合评分:%.2f\n",i+1,averageScore);}}6.3字符数组的定义和应用存储和处理字符串字符数组的定义与引用一般形式与普通一维数组类似,类型说明符为char。语法格式如下:char数组名[常量表达式];示例:chara[10];//定义了一个包含10个字符元素的数组元素引用通过下标访问单个字符,赋值与输出示例:str[0]='H';str[1]='i';//输出结果为"Hi"printf("%c%c\n",str[0],str[1]);重要提示:单纯的字符集合≠字符串。C语言字符串需要特殊的结束标志。字符数组的初始化方式一:逐个字符初始化charstr[5]={'H','e','l','l','o'};与普通一维数组初始化方式一致,需手动指定每个元素。方式二:字符串常量初始化charstr[6]="Hello";系统自动添加结束符'\0',数组长度需预留位置。方式三:省略数组长度(自动计算)charstr[]="Hello";编译器自动计算长度并包含结束符,此处str长度为6。推荐在不确定长度时使用此方式。字符数组的输入与输出字符串输出方法1.printf函数(%s格式符)charstr[]="Hello";printf("%s\n",str);//输出直到遇到'\0'结束2.puts函数puts(str);//自动添加换行符,使用更简洁字符串输入方法1.scanf函数(%s格式符)charstr[20];scanf("%s",str);⚠注意:遇空格/回车停止,无法读取含空格字符串2.gets函数(读取整行)gets(str);//读取整行,包括空格⚠警告:存在缓冲区溢出风险,建议使用fgets例6-5:输出字符串练习#include<stdio.h>main(){chara[26]="Ilikeplayingbasketball";inti;for(i=0;i<26;i++)printf("%c",a[i]);
}例6-6:输入字符串“abcdefghi”输出#include<stdio.h>main(){
charstr[10];scanf("%s",str);printf("%s",str);
}实例体验例6-7:getchar
putchar练习#include<stdio.h>main(){charc1,c2,c3;c1=getchar();c2=getchar();c3=getchar();putchar(c1);putchar(c2);putchar(c3);}例6-8:不同格式字符串输出#include<stdio.h>main(){
charstr1[20];charstr2[5][10];gets(str1);for(inti=0;i<3;i++){
gets(str2[i]);
}
puts(str1);for(inti=0;i<3;i++){
puts(str2[i]);
}}实例体验实例体验例6-9:用字符数组探索《静夜思》用字符数组探索《静夜思》问题描述:唐诗宋词作为中华民族传统文化的瑰宝,承载着深厚的文化底蕴和艺术价值。这些经典作品以简洁精妙的语言、和谐优美的韵律以及深远独特的意境,展现了古代文人的卓越智慧和丰富情感,宛如中华文化长河中璀璨夺目的明珠。接下来,我们将用C语言的字符数组来统计唐诗《静夜思》的长度,并且输出前10个字符。程序代码#include<stdio.h>#include<string.h>main(){
//定义并初始化字符数组,存储古诗词
charpoem[100]="床前明月光,疑是地上霜。举头望明月,低头思故乡。";
printf("古诗词内容为:\n%s\n",poem);//计算并输出古诗词的长度(不包括结尾的'\0')intlen=strlen(poem);
printf("古诗词的长度为:%d\n",len);//使用字符串处理函数实现特定功能
charsubStr[20];
strncpy(subStr,poem,10);//复制前10个字符到subStr
subStr[10]='\0';//添加字符串结束符
printf("复制的前10个字符为:%s\n",subStr);}6.4趣味实例—“狼追兔子”问题综合运用数组和循环趣味实例实训目的1.了解数组的基本用法。2.熟悉数组的定义、引用和初始化。3.了解数组在编程中的注意事项。实训内容基础训练:用C语言解决“狼追兔子”的问题一只兔子躲进了10个环形分布的洞的某一个,狼在第1个洞没有找到兔子,就隔
一个洞,到第3个洞去找,也没有找到,就隔两个洞,到第6个洞去找,以后每次多隔一个洞去找兔子……这样下去,结果一直找不到兔子(设寻找的最大次数为100),请问:兔子可能躲在哪个洞中?实训流程知识准备设计算法基础训练1)编写程序2)上机验证编程提示数据表示:数组a[10]标记洞的访问状态(0/1)位置计算:n+=(i+1);//每次多隔1个洞
x=n%10;//取余,往回找循环模拟:若访问到已标记的洞,则进入死循环,永远找不到趣味实例:“狼追兔子”问题程序代码:#include<stdio.h>main(){inta[10];//10个洞
inti,n=0,x=0;//n为累加洞编号,x为洞下标for(i=0;i<10;i++)//数组初始化为1,标记兔子可能藏在各个洞中a[i]=1;for(i=0;i<100;i++){
//设最大寻找次数为100
n+=(i+1);//每次多隔1个洞
x=n%10;//取余,往回找
a[x]=0;//访问过的洞标记为0,说明没有兔子}for(i=0;i<10;i++){if(a[i])//狼未访问过的洞,说明可能有兔子
printf("兔子可能在第%d个洞中\n",i+1);}}本章小结:补充延申:常用字符串处理函数strlen(str)-计算字符串长度功能:计算实际字符个数,不包含结束符'\0'示例:strlen("Hello")返回值为5strcpy(str1,str2)-字符串复制功能:将str2复制到str1,包含'\0'注意:确保str1长度足够容纳str2strcat(str1,str2)-字符串连接功能:将str2追加到str1末尾,结果存于str1示例:strcat(str1,"World!")连接字符串strcmp(str1,str2)-字符串比较规则:按ASCII码值比较,返回负数/0/正数示例:strcmp("Apple","Banana")返回负数小小顶梁柱—函数C语言程序设计第七章本章目录01.函数的定义02.函数的调用03.函数的声明04.变量的作用域05.趣味实例7.1函数的定义将功能封装为独立模块定义函数一般形式类型说明符函数名(形参列表)
{说明部分执行部分}各部分详解“类型说明符”是指函数返回值的类型。函数类型可以省略,当不指明函数类型时,系统默认的是整型。函数名:遵循标识符命名规则,不可省略,用于调用函数形参列表:函数的输入接口,接收外部传递的数据。函数体:包裹在{}中的代码块,实现具体功能,函数内部应有自己的说明语句和执行语句,花括号{}是不可以省略的。函数的参数形式参数(形参)函数定义时括号内声明的变量,仅在函数内部有效(局部变量)。作用是接收调用者传递的数据,作为函数执行的输入。实际参数在函数调用中传递数据的参数称为实际参数,简称实参。代码示例例如:求两个整数的较大者的max函数,在该程序中,子函数中的变量x、y是形参,主函数中的变量a、b是实参。函数参数说明实例函数的参数函数参数说明:1)函数的形参可以有多个,可以相同类型,也可以是不同类型,如intmax(intx,inty)或者intmax(intx,floaty)。相同类型也不可以省略形参前的类型说明,如intmax(intx,y)。2)形参必须是变量,但实参可以是常量、变量和表达式,例如C=max(10,a+b)。3)实参类型必须与形参类型兼容。4)在C语言中,函数进行的是“值传递”,将实参的值传递给形参。这种传递是单向的,即形参的变化并不传递给实参。这是由于形参和实参在内存中分别占用不同的内存单元,形参单元的值改变不会影响到实参单元中的值。函数的参数在函数max()中x、y的值有变化时,在main()函数中实参a和b的值仍然是5和6。因为值的传递是a—>x,b—>y,但不能反向传递,这就是“单向值传递”函数参数传递参数传递示意图函数的返回值函数的返回值--return语句功能:使程序控制从被调用函数返回到调用函数中,同时把返回值带给调用函数。作用:函数与外界交互的重要接口,传递计算结果。return语句书写形式return(表达式);
或return表达式;
或return;使用说明:1)
函数中可有多个return语句,但每次只能有一条被执行。2)若函数类型与return语句中表达式值的类型不一致,按前者为准,此时系统将对数值进行类型转换。3)如果明确表示不需要返回值,可用void型函数,
即定义函数时,类型定义为void型,而且函数中可不必使用return语句。4)
如果函数中没有return语句,并不代表没有返回值,而是返回
一
个不确定的值。实例体验:分析:前面学习的圆面积编程是在主函数中编写的,本例中用子函数编写,其程序段与以前类似,只不过要确定函数名、参数和返回值等内容。例7-1定义一个函数,其功能是已知半径r,求圆的面积。程序代码:floatcirclearea(intr){floatarea;area=3.14*r*r;return(area);}实例体验:问题描述:棋盘上的米粒在一个古老的王国里,国王为了奖励一位聪明的数学家,决定在棋盘上放米粒作为奖励。第1个格子放1粒米,第2个格子放2粒,第3个格子放6粒,第4个格子放24粒…每个格子的米粒数都是前一个格子数的倍数。数学家微笑着对国王说:"陛下,这个奖励看似简单,但随着格子数的增加,米粒数会迅速增长,最终会超出您的想象。"国王不以为然,认为这不过是些小数目。然而,
当数学家计算出第20个格子的米粒数时,国王惊呆了—那是一个天文数字!这就是求解阶乘的故事。下面我们尝试使用函数来解决求阶乘的问题。例7-2求阶乘—函数的优越性。实例体验:程序代码:#include<stdio.h>longfactorial(intn){inti,result=1;for(i=1;i<=n;i++)result*=i;returnresult;}例7-2求阶乘—函数的优越性。main(){intnum1,num2;printf("请输入两个整数:");scanf("%d%d",&num1,&num2);printf("%d!=%ld\n",num1,factorial(num1));printf("%d!=%ld\n",num2,factorial(num2));}7.2函数的调用使用已定义的功能模块函数的调用形式函数的调用形式主函数使用被调函数的功能,称为函数的调用。在C语言中,只有在函数调用时,函数体中定义的功能才会被执行。C语言中函数调用的一般形式为:函数名(类型形参,类型形参,…);对无参函数调用时,则无实际参数表。实际参数表中的参数可以是常数、变量或其他构造类型数据及表达式,各实参之间用逗号分隔。例如:d=max(a,b);或d=max(3,a);或d=max(max(a,b),c)函数的调用形式函数表达式表达式包含函数项时,要求函数必须有返回值,以函数的返回值参与表达式的运算。“z=max(x,y);”是一个赋值表达式,把max的返回值赋予变量z函数语句函数调用的一般形式加上分号即构成函数语句。无论函数是否有返回值,都可用这种方式调用。printf("%d",a);scanf("%d",&b);函数实参函数可以作为另一个函数调用的实际参数出现,这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须有返回值。printf("%d",max(x,y));/*把max()调用的返回值作为printf()函数的实参*/函数调用的语法要求语法规则1)调用函数时,定义和说明的函数名必须与被调用的函数名完全一样;实参的个数、类型和形参的个数、类型一致。2)C语言规定函数必须先定义,后调用,即被调用的函数必须在调用之前加以说明或在调用函数之前定义。3)C语言中的函数定义都是相互平行的、独立的,不允许嵌套定义函数,但允许嵌套调用函数(在调用一个函数的过程中,再调用另一个函数)main(){intmax(intx,inty);inta,b;intc;scanf("%d,%d",&a,&b);c=max(a,b);printf("Maxis%d\n",c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}
7-3找出两个整数的最大值程序执行流程实例体验:实例体验:问题描述:智能书法评分系统在中华传统文化中,书法是一门极具艺术价值的技艺。随着现代科技的发展,我们可以通过计算机程序来辅助评估书法的质量。假设你正在开发一个“智能书法评分系统”,该系统可以根据用户输入的书法作品的笔画长度、笔画粗细、字形结构等参数,自动计算出书法作品的评分。例7-4传统文化与现代科技的结合—智能书法评分系统。实例体验:程序代码:#include<stdio.h>floatscore(floatlen,floatthi,floatstr)//计算书法评分的函数{return(len*0.4)+(thi*0.3)+(str*0.3);}voidprint(floats)//输出评分和评价的函数{printf("书法作品评分为:%.2f\n",s);if(s>=90){printf("评价:优秀\n");}elseif(s>=70){printf("评价:良好\n");}elseif(s>=60){printf("评价:及格\n");}else{printf("评价:需要改进\n");}}main(){floatlen,thi,str;printf("请输入书法作品的笔画长度评分:");scanf("%f",&len);printf("请输入书法作品的笔画粗细评分:");scanf("%f",&thi);printf("请输入书法作品的字形结构评分:");scanf("%f",&str);floats=score(len,thi,str);//调用函数计算评分print(s);//调用函数输出评分和评价}例7-4传统文化与现代科技的结合—智能书法评分系统。7.3函数的声明告诉编译器函数的存在函数声明的格式在主调函数中调用某函数之前,应对该被调函数进行声明,其作用是使编译系统知道被调函数返回值的类型,以便在主调函数中按此种类型对返回值进行相应的处理。书写格式与说明一般形式:类型说明符被调函数名(类型形参,类型形参,…);1.在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:intmax(int,int);2.函数的声明和函数的定义有本质上的不同,主要区别在以下两个方面:1)函数的定义是编写一段程序,应有函数的具体功能语句—函数体;而函数的声明仅是向编译系统的一个说明,不含具体的执行动作。2)在程序中,函数的定义只能有一次,而函数的声明可以有多次。函数声明的位置与作用域函数声明位置:函数内或函数外。intmax(intx,inty);main(){intmax(intx,inty);inta,b;intc;scanf("%d,%d",&a,&b);c=max(a,b);printf("Maxis%d\n",c);}intmax(intx,inty){intz;z=x>y?x:y;return(z);}
小贴士:在下列情况下,无需进行函数声明:1)被调用函数定义出现在主调函数之前,如上例中,将max()函数段写在主函数的前面max()函数就可以不声明。2)若函数返值是int或char型,也可不声明函数,系统自动按int型处理。在所有函数外部声明被调用函数,其后所有函数都可以调用该函数在调用函数内部声明被调用函数,只有调用函数内部才可调用该函数实例体验:程序代码:fun1(inta,intb){intc;a+=a;b+=b;c=fun2(a,b);returnc*c;}fun2(inta,intb){intc;c=a*b%5;returnc;}main(){intx=21,y=12;printf(“fun1(x,y)=%d,”,fun1(x,y));printf(“x=%d,y=%d”,x,y);}例7-6运行下面的程序,观察现象,找出原因并修改程序。7.4变量的作用域变量在何处起作用局部变量核心定义局部变量是在函数内部声明的变量,包括函数的形参。这些变量只在声明它的函数内部使用,在函数外不能使用,即“谁声明谁使用”说明1)形参属于局部变量。2)main()函数中定义的变量只在main()函数中有效,不能因为在main()函数中定义就在整个文件或程序中有效。main()函数也不能使用其他函数中定义的变量。3)不同函数中的同名变量,占有不同内存单元,因此不会相互影响。4)复合语句中定义的变量也属于局部变量,变量的作用域在复合语句内,这种复合语句也称为“分程序”或“程序块”。代码示例(C语言)floatf1(inta){intb,c;…}charf2(intx,inty){inti,j;…}main(){intm,n;…}a、b、c有效x、y、i、j有效m、n有效全局变量核心定义在函数外定义的变量称为全局变量,又称全程变量或外部变量。全局变量的有效范围是从定义的位置直至它所在源程序文件的结束。说明1)全局变量的作用域从定义位置开始,在这个范围内的任何地方都可使用(包括函数中)。2)全局变量可以作用于它所在的整个程序或外部的程序,但需要另外说明,其存储类型也会影响其作用的范围。3)若全局变量与局部变量同名,则全局变量被屏蔽。4)全局变量的使用增加了函数之间传递数据的途径。当函数需返回多个结果时,可通过全局变量实现数据传递。5)应尽量少使用全局变量,因为全局变量在程序执行过程中占用存储单元,若使用过多,很难判断出全局变量的当前值,因此降低程序清晰性,容易出错。实例体验:程序代码:#include<stdio.h>sub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}main(){inta,b;a=3;b=4;sub();printf("main:a=%d,b=%d\n",a,b);printf("main:a=%d,b=%d\n",a,b);}例7-7局部变量示例实例体验:问题描述:古代天文历法与现代气象预测在中国古代天文历法中,如24节气,展现了中华民族在天文观测和气象预测方面的卓越智慧。随着现代科技的发展,我们可以通过计算机程序来模拟和监测节气温度变化,从而更精准地预测天气。请开发一个“节气温度监测系统”,根据用户输入的节气温度数据,判断当前温度是否在正常范围内,并输出相应的提示信息。例7-8古代天文历法与现代气象预测—节气温度监测系统实例体验:程序代码:#include<stdio.h>sub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}main(){inta,b;a=3;b=4;sub();printf("main:a=%d,b=%d\n",a,b);printf("main:a=%d,b=%d\n",a,b);}例7-8
古代天文历法与现代气象预测—节气温度监测系统实例体验:程序代码:#include<stdio.h>floatminTemp,maxTemp;voidtemperature(floattemp){if(temp<minTemp){printf("温度过低,注意保暖\n");}elseif(temp>maxTemp){printf("温度过高,注意防暑\n");
例7-8
古代天文历法与现代气象预测—节气温度监测系统}else{printf("温度正常\n");}}main(){floattemp;printf("请输入正常范围的下限:");scanf("%f",&minTemp);printf("请输入正常范围的上限:");scanf("%f",&maxTemp);printf("请输入当前温度:");scanf("%f",&temp);temperature(temp);}7.5趣味实例—四则运算编程综合运用函数知识趣味实例:四则运算编程实训目的1.掌握函数定义的方法。2.掌握函数实参与形参的关系以及“值传递”的方式。3.了解全局变量、局部变量的使用和区别。实训内容1.基础训练由计算机生成简单的一位数四则运算题,用户给出答案,计算机判断对错,直到用户回答说“不再继续做了”时,结束程序。2.提升训练让用户选择指定加减乘除哪一种运算,以及出一位数还是两位数的运算题,对用户所做算术题的对错次数进行记录,结束程序时给出成绩。结束程序要求同上。实训流程知识准备学会函数的使用编程训练1)内容分析:确定程序的操作确定四则运算中的变量明确四则运算的运算过程2)编程分工。3)编程、上机验证。编程提示四则运算(加、减、乘、除)的核心流程具有高度相似性,可以先编出一种运算的模式,再将其推广到其他运算。分析时,构建出整个程序的结构模型,帮助分析程序的需求及走向。编程时,从分析的结构中先编写底层函数模块,然后再向上编写。本章小结:魅力指挥棒—指针的应用C语言程序设计第八章本章目录01.认识指针02.指针变量的定义及引用03.指针与数组04.趣味实例8.1认识指针理解内存地址与指针的概念指针概念及作用
当在程序中定义了一个变量,对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就是“地址”。由于通过地址能找到所需的变量单元,因此唯一标识变量储存位置的地址,通常称为“指针”。C语言中的地址包括位置信息(内存编号,或称纯地址)
和它所指向的数据的类型信息,或者说它是“带类型的地址”。存储单元的地址和存储单元的内容是两个不同的概念。例如:inti=1,j=2,k=3;//设int变量占2字节指针变量指针变量
用一个变量来存放内存的地址,这个变量就称为指针变量,指针类型丰富多样,但不同类型指针变量所占用的存储单元长度是相同的。在程序中一般是通过变量名来引用变量的值。直接按变量名进行的访问,称为“直接访问”方式。还有一种“间接访问”的方式,即将变量的地址存放在另一变量(指针变量)中,然后通过该指针变量来找到对应变量的地址,从而访问变量。
严格地说,一个指针是一个地址,是一个常量。而一个指针变量却可以被赋予不同的指针值,是变量。但常把指针变量简称为指针。为了避免混淆,我们约定:“指针”是指地址,是常量,“指针变量”是指取值为地址的变量。定义指针的目的是为了通过指针去访问内存单元。例如:将变量x的地址2060存放到另一个变量p中,即p的值为2060,这样通过变量p可以找到变量x的地址,从而找到x的值。存放地址的变量p就是指针变量。可以形象地说,p指向x,变量x与指针变量p的关系如图8-2所示。
8.2指针变量的定义及引用掌握指针变量的基本操作指针变量的定义定义格式类型标识符*指针变量名;例如:int*pointer_1,*pointer_2;//定义了两个int类型的指针变量类型标识符决定指针指向的数据类型,必须与目标变量类型严格一致。星号*指针运算法,表示其后的变量是指针变量,不能省略。指针变量名遵循C语言标识符命名规则,用于存储内存地址。结构说明1)定义指针变量时必须指定其类型。一个变量的指针的含义包括两个方面,一是以存储单元编号表示的纯地址,二是它指向的存储单元的数据类型。2)如何表示指针类型。指向整型数据的指针类型表示为“int*”,读作“指向int类型的指针”或简称“int指针”。3)指针不能指向常量,例如“int*p;p=&50;”是错误的。4)指针的内容不能直接输入,例如“intp;scanf("%d",&p);”是错误的,“int*p,a;p=&a;scanf("%d",p);”是正确的,此处是输入变量a的值。定义指针变量要注意:指针变量的定义示例指针类型指针定义语句里的指针名字去掉,剩下的部分就是这个指针的类型。指针所指向的类型通过指针来访问指针所指向的内存区域时,指针所指向的类型决定了编译器将把那片内存区里的内容当作什么类型来看待。int*ptr;//指针的类型是int*char*ptr;//指针的类型是char*int**ptr;//指针的类型是int**int(*ptr)[3];//指针的类型是int(*)[3]示例int*ptr;//指针所指向的类型是intchar*ptr;//指针所指向的类型是charint**ptr;//指针所指向的类型是int*int(*ptr)[3];//指针所指向的类型是int()[3]指针的引用
在指针的引用中涉及两个运算符"*"和"&","*"是指针运算符,或称为“间接访问”运算符,如*p1表示指针变量p1所指向的变量;"&"称为取地址运算符,如为了让指针p指向变量x,可执行p=&x,此时变量x的地址即存入了指针p中。若要改变x变量的值,也可通过改变*p的值来实现,如执行“*p=47;”,则此时x=47。
指针变量既可以在定义时初始化,也可以在定义后赋初值,不能未赋值就引用指针存取值。指针变量可以如同一般变量一样进行赋值、加减计算。指针的引用取地址运算符`&`作用:获取变量的内存地址格式:&变量名示例:p=&a;(将变量a的地址赋值给指针p)解引用运算符`*`作用:访问指针指向的内存值格式:*指针变量名示例:printf("%d",*p);(输出p指向的值)*p=20;(修改p指向的变量值)指针变量的初始化野指针的危害未初始化的指针值随机,指向内存任意位置。直接使用(如*p=10)可能导致程序崩溃或数据被意外篡改。(补充内容)指针的初始化定义时直接赋值:
inta,*p=&a;先定义后赋值:
inta,*p;p=&a;空指针
NULLNULL通常定义为0,表示指针无效。良好习惯:int*p=NULL;注意:NULL指针不可解引用(*p)。(补充内容)指针的引用说明指针变量中只能用于存储变量的地址,不可将一个整型常量赋给一个指针变量。实例体验例8-1通过指针变量访问变量。#include<stdio.h>main(){inta=7,b=5,c,*pa=&a,*pb;pb=&b;c=*pa+*pb;printf("a=%d,*pa=%d\n",a,*pa);printf("b=%d,*pb=%d\n",b,*pb);printf("%d+%d=%d\n",a,b,c);printf("%d+%d=%d",*pa,*pb,c);}#include<stdio.h>main(){int*p,*pa,*pb,a,b;printf("请输入两个整数:");scanf("%d,%d",&a,&b);pa=&a;pb=&b;if(a<b){p=pa;pa=pb;pb=p;}printf("a=%d,b=%d\n",a,b);printf("从大到小输出两个整数:%d,%d\n",*pa,*pb);}例8-2输入a和b两个整数,按先大后小的顺序输出a和b两个整数,使用指针编写程序。8.3指针与数组利用指针高效操作数组指针与一维数组
数组一旦被定义,其元素将在内存中占用一段连续的存储单元,每个数组元素都占用一个存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组指针,是指数组的起始地址,数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素。
数组名代表数组的首地址。比如“int[5]={12,34,56,78,90};”首地址是数组的第1个元素的地址,所以该数组的数据在内存中的存储结构如图
所示。。指针与一维数组指针与一维数组建立关联将数组的首地址放入指针中,就让指针变量指向数组,如:inta[5],*p=a;//指针变量p指向数组a。一维数组的引用——引用各个数组元素的地址
1)通过使用数组名引用。如“inta[6]”2)通过指针引用。如“inta[6],*p=a;p++;”注意:此处数组名a是常量,不能进行自增/自减运算。指针与一维数组一维数组的引用——引用各个数组元素所在的存储单元或存储单元里的值
1)通过对数组名、指针变量的取内容运算符*。上图
中数组的运算:*p=a[0],*(p+1)=a[1],a=a[0],*(a+1)=a[1],依次类推。2)通过指针变量后面跟下标。数组和指针建立关联后,可以把指针带入数组名引用各个数组元素,即p[i]与a[i]代表值相同。小贴士:1)指针变量指向数组元素a[i]的方法是p=&a[i]或p=a+i。2)与数组名的区别,指针变量是一个变量,其值可以改变,数组名是数组的首地址,是地址常量,其值不能变化。例如,若定义“inta[10],*p=a;”,则a++是错误的,p++是允许的。3)未初始化的指针指向不确定的值。4)若有定义“inta[10],*p=a,i;”,则a[i]、*(a+i)、*(p+i)等价。5)注意指针的动态性,a[i]与*(p+i)不总是相等的,例如:inta[10],*p,i=5;p=a+1;上述例子中*(p+i)等价于a[6]。指针与二维数组二维数组定义二维数组定义时的行数和列数分别用两个方括号分开,把二维数组看作是一种特殊的一维数组。指针与二维数组建立关联二维数组的引用:同一维数组。小贴士:设“inta[4][5],*p=a[0],i,j;”。1)a是该二维数组的首地址,即元素a[0][0]的首地
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年康马县带编教师招聘考试备考试题及答案解析
- 2026年二级建造师《建设工程经济》模拟考试题(含详细答案解析)
- 2026年桃江县带编教师招聘考试参考题库及答案解析
- 2026年长白朝鲜族自治县带编教师招聘考试参考题库及答案解析
- 2026年天柱县带编教师招聘笔试参考题库及答案解析
- 2026年云阳县带编教师招聘笔试模拟试题及答案解析
- 2026年南澳县带编教师招聘考试模拟试题及答案解析
- 2026年通化县带编教师招聘考试参考题库及答案解析
- 2026年修文县带编教师招聘考试参考题库及答案解析
- 2026年肇州县带编教师招聘考试参考题库及答案解析
- 《金属非金属矿山建设项目安全预评价报告编写提纲》解读
- 《生物能源》课件
- 装修工程安全专项施工方案
- 《民族文化的瑰宝》课件
- 棉花病虫害防治技术
- GB/T 6663.1-2007直热式负温度系数热敏电阻器第1部分:总规范
- GB/T 308.1-2013滚动轴承球第1部分:钢球
- GB/T 16601.2-2017激光器和激光相关设备激光损伤阈值测试方法第2部分:阈值确定
- GB/T 10802-2006通用软质聚醚型聚氨酯泡沫塑料
- 企业清产核资工作底稿模板-会计师事务所
- (人教部编版)二年级上册语文课课练(全册)含答案
评论
0/150
提交评论