实验4循环结构程序设计 4.1基本的循环程序设计 【实验目的】 1.掌握循环程序设计的基本概念: 2.熟练掌握用while、do-while和for语句实现循环的方法: 3.能够用循环实现一些常用的基本算法: 4.学习如何调试程序。 【相关知识点】 1.for循环语句一般格式 for循环语句的一般格式为: for(表达式1;:表达式2:表达式3) 循环体语句 示例: int i,sum=0; for(i=1;i<=10;i++) { sum=sum+1; printf("%d",sum); 该示例是求1+2+3+…+10之和。 for语句的执行步骤如下: (1)求解表达式1: (2)求解表达式2,若其值为非0(逻辑真),则执行循环体语句,然后执行第(3)步。 若其值为0(逻辑假),则结束循环,转到第(5)步: (3)求解表达式3: .59-
实验 4 循环结构程序设计 4.1 基本的循环程序设计 【实验目的】 1. 掌握循环程序设计的基本概念; 2. 熟练掌握用 while 、do-while 和 for 语句实现循环的方法; 3. 能够用循环实现一些常用的基本算法; 4. 学习如何调试程序。 【相关知识点】 1. for 循环语句一般格式 for 循环语句的一般格式为: for(表达式 1;表达式 2;表达式 3) 循环体语句 示例: int i,sum=0; for(i=1;i<=10;i++) { sum=sum+i; } printf("%d",sum); 该示例是求 1+2+3+……+10 之和。 for 语句的执行步骤如下: (1) 求解表达式 1; (2) 求解表达式 2,若其值为非 0(逻辑真),则执行循环体语句,然后执行第(3)步。 若其值为 0(逻辑假),则结束循环,转到第(5)步; (3) 求解表达式 3; - 59 -
(4)转向(2)继续执行: (5) 循环结束,执行for语句下面的一个语句。 一般表达式1用于对循环变量赋初值,表达式2为循环条件,通常是关系表达式或逻 辑表达式,也可以是数值表达式或字符表达式,不管表达式2是什么类型,只要其值为非0, 就执行循环体。表达式3用于循环变量值,使得循环条件能够趋于结束,在上述示例中为 i+,使得最终i>10,循环结束,执行for语句下面的语句: printf("%od".sum): 值得注意的是,for语句中的表达式1、表达式2和表达式3都可以省略,用于构成循 环体算法。 2.while循环语句一般格式 while循环语句一般格式为: while(表达式) 循环体语句 示例: int i=1,sum=0; while(i10”的语句,这里使用的是“i+,” 语句来达到此目的。如果无此语句,则i的值始终不变,循环永不会结束。 3.do-while循环语句一般格式 do-while循环语句一般格式为: do -60-
(4) 转向(2)继续执行; (5) 循环结束,执行 for 语句下面的一个语句。 一般表达式 1 用于对循环变量赋初值,表达式 2 为循环条件,通常是关系表达式或逻 辑表达式,也可以是数值表达式或字符表达式,不管表达式 2 是什么类型,只要其值为非 0, 就执行循环体。表达式 3 用于循环变量值,使得循环条件能够趋于结束,在上述示例中为 i++,使得最终 i>10,循环结束,执行 for 语句下面的语句: printf("%d",sum); 值得注意的是,for 语句中的表达式 1、表达式 2 和表达式 3 都可以省略,用于构成循 环体算法。 2. while 循环语句一般格式 while 循环语句一般格式为: while(表达式) 循环体语句 示例: int i=1,sum=0; while(i10”的语句,这里使用的是“i++;” 语句来达到此目的。如果无此语句,则 i 的值始终不变,循环永不会结束。 3. do-while 循环语句一般格式 do-while 循环语句一般格式为: do - 60 -
{循环体语句} while(表达式)方 示例: int i=1.sum=0: do sum=sum+1; itt, }while(i100)break; printf("radius-%f area=%f\n",radius,area); } 该示例是计算半径radius从1变化l0时的圆面积,直到面积area大于100为止。从上面 的for循环可以看到,当area>lO0时,执行break语句,循环提前结束,即不再继续执行其余 -61-
{ 循环体语句 } while(表达式); 示例: int i=1,sum=0; do { sum=sum+i; i++; } while(i100) break; printf("radius=%f,area=%f\n", radius,area); } 该示例是计算半径 radius 从 1 变化 10 时的圆面积,直到面积 area 大于 100 为止。从上面 的 for 循环可以看到,当 area>100 时,执行 break 语句,循环提前结束,即不再继续执行其余 - 61 -
的几次循环。 continue语句的一般形式为: continue; continue语句的作用是结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下 一次是否执行循环的判定。 continue语句和break语句的区别是:continue语句只结束本次循环,而不是终止整个循 环语句的执行。而break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。 示例: int i,sum=0; for(i=1;i<100;i+) ifi%3=0) continue; sum=sum+i; } 该示例是计算100以内不能被3整除的数之和。当i能被3整除时,执行continue语句, 结束本次循环(即跳过sum=sum+i语句),只有i不能被3整除时执行sum=sum+i,语句。 【实验任务】 一、读程序改错 该部分实验主要训练学生读简单程序的能力,并在理解程序的基础上,改正程序中出现 的问题,这些问题都是初学者经常容易犯的错误,针对基本的循环结构程序设计这部分,主 要有如下问题: 1)不能正确表达循环体: 2)没有正确修改循环变量的值,导致循环结束条件不成立而不能结束循环: 3)循环变量或其他循环体中用到的变量没有正确赋初值: 4)break语句与continue语句使用混淆。 针对上面出现的问题,查找下面程序中存在的问题,并改正调试。 1.打开c:lc-programming4pg4101.cpp,该程序有一个小问题,请修改,使程序能正确运 .62-
的几次循环。 continue 语句的一般形式为: continue; continue 语句的作用是结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下 一次是否执行循环的判定。 continue 语句和 break 语句的区别是:continue 语句只结束本次循环,而不是终止整个循 环语句的执行。而 break 语句则是结束整个循环过程,不再判断执行循环的条件是否成立。 示例: int i,sum=0; for(i=1;i<100;i++) { if(i%3==0) continue; sum=sum+i; } 该示例是计算 100 以内不能被 3 整除的数之和。当 i 能被 3 整除时,执行 continue 语句, 结束本次循环(即跳过 sum=sum+i;语句),只有 i 不能被 3 整除时执行 sum=sum+i;语句。 【实验任务】 一、读程序改错 该部分实验主要训练学生读简单程序的能力,并在理解程序的基础上,改正程序中出现 的问题,这些问题都是初学者经常容易犯的错误,针对基本的循环结构程序设计这部分,主 要有如下问题: 1) 不能正确表达循环体; 2) 没有正确修改循环变量的值,导致循环结束条件不成立而不能结束循环; 3) 循环变量或其他循环体中用到的变量没有正确赋初值; 4) break 语句与 continue 语句使用混淆。 针对上面出现的问题,查找下面程序中存在的问题,并改正调试。 1.打开 c:\c-programming\4\pg4101.cpp,该程序有一个小问题,请修改,使程序能正确运 - 62 -
行。修改后的程序以pg4101_ok.cpp保存。该源程序内容如下: #include void main(void) int i; for(i=l;i<ll;i++); { printf("本信息将被显示l0次!n")方 } 了提示:如何发现问题? 编译、链接该程序后,使用工具栏上的按钮或者快捷键F10命令,启用单步运行程序, 这时调试窗口的变量观察区会自动出现,当单步运行到 for(i=1;i<1l;i+)方 语句时,循环变量i一次就变为11,也就是for语句执行了10次,而下面设置的循环句 printf("本信息将被显示l0次!n"); 却没有被执行,从中发现问题,原因是for认为括号之后的分号“:”,即空语句为循环体。 改正程序后的运行结果示例如图4.1.1所示。 "C:lc-programming\4\Debug\pg4101_ok.exe" 回☒ 本信夏将被显示1次: 本信 将被显示1次: 本信息将被显示1次: 本信夏,将被显示1次: 本信息 将被显示1次: 本信息将被显示10次: 本信息将被显示1次: 本信息,将被显示1次: 本信息 将被显示10次: 本信息将被显示1次: Press any key to continue 图4.1.1pg4101_ok.cpp的运行结果 2.打开c:lc-programming4pg4102.cpp,该程序是从键盘上输入一批学生的成绩,以负数 作为数据输入结束的标识。输入结束后计算其中及格的人数。请修改,使程序运行得到正确 的结果。修改后的程序以pg4102 ok.cpp保存。该源程序内容如下: -63-
行。修改后的程序以 pg4101_ok.cpp 保存。该源程序内容如下: #include void main(void) { int i; for(i=1;i<11;i++) ; { printf("本信息将被显示 10 次!\n"); } } 提示:如何发现问题? 编译、链接该程序后,使用工具栏上的 按钮或者快捷键 F10 命令,启用单步运行程序, 这时调试窗口的变量观察区会自动出现,当单步运行到 for(i=1;i<11;i++); 语句时,循环变量 i 一次就变为 11,也就是 for 语句执行了 10 次,而下面设置的循环句 printf("本信息将被显示 10 次!\n"); 却没有被执行,从中发现问题,原因是 for 认为括号之后的分号“;”,即空语句为循环体。 改正程序后的运行结果示例如图 4.1.1 所示。 图 4.1.1 pg4101_ok.cpp 的运行结果 2.打开 c:\c-programming\4\pg4102.cpp,该程序是从键盘上输入一批学生的成绩,以负数 作为数据输入结束的标识。输入结束后计算其中及格的人数。请修改,使程序运行得到正确 的结果。修改后的程序以 pg4102_ok.cpp 保存。该源程序内容如下: - 63 -
#include≥ void main(void) int count,grades; printf("请输入分数:n")方 scanf("%d",&grades); while(grades>=0) { if(grades>=60)count++; } printf("共有%d个学生成绩合格!n",count); 了提示:如何发现问题? 编译、链接该程序后,使用工具栏上的不按钮或者快捷键F10,启用单步运行程序此时 VC+6.0的窗口的标题栏显示如图4.1.2所示。 Xpg4102-创天中文Vc++[break]-[pg4102cpp】 图4.1.2程序调试状态表示 表示程序正处于调试运行状态。这时调试窗口的变量观察区会自动出现,切换到Locals 标签,观察程序中的局部变量值的变化情况,在没有输入数据之前,变量grades和count的值 为随机数,如图4.1.3所示,当单步执行到“scanf("%d",&grades),”语句时,如图4.1.4所示, 此时表示程序的执行流程切换到DOS窗口输入成绩,如图4.1.5所示。 0上下 main0 Name Value grades -858993460 count -858993460 Auto Locals this/ 图4.1.3程序开始运行变量的初始值 %pg4102-创天中文Vc++[un]-[pg4102.cpp) -64-
#include void main(void) { int count,grades; printf("请输入分数:\n"); scanf("%d",&grades); while(grades>=0) { if(grades>=60) count++; } printf("共有%d 个学生成绩合格!\n",count); } 提示:如何发现问题? 编译、链接该程序后,使用工具栏上的 按钮或者快捷键 F10,启用单步运行程序此时 VC++6.0 的窗口的标题栏显示如图 4.1.2 所示。 图 4.1.2 程序调试状态表示 表示程序正处于调试运行状态。这时调试窗口的变量观察区会自动出现,切换到 Locals 标签,观察程序中的局部变量值的变化情况,在没有输入数据之前,变量 grades 和 count 的值 为随机数,如图 4.1.3 所示,当单步执行到“scanf("%d",&grades);”语句时,如图 4.1.4 所示, 此时表示程序的执行流程切换到 DOS 窗口输入成绩,如图 4.1.5 所示。 图 4.1.3 程序开始运行变量的初始值 - 64 -
图4.14程序运行状态表示 "clc-programming\4 Debug\po41o2.exe”=▣x 请输入分数:?8 图4.1.5切换到数据输入窗口 数据输入结束后,切换回VC+6.0,观察此时的变量值,如图4.1.6所示,grades的值为 刚刚输入的78,cout的值在原来随机初始值上加1,但是这个值显然是不正确的,不能真实 的反映所统计的及格的人数。继续单步运行程序发现grades的值一直保持不变,只是count 的值在变化。通过以上单步追踪运行,可以发现问题所在。 g上下main0 Name Value grades 78 count -858993459 4 Auto Locals this☑ 图4.1.6执行一次循环体后,变量值的变化情况 改正程序后的运行结果示例如图4.1.7所示。 "C:\c-programming\4\Debug\pg4102_ok.exe" 回☒ 请输入分数:788967875864905943-1 共有6个学生成绩合格! Press any key to continue 图4.1.7pg4102_ok.cpp的运行结果 3.打开c:c-programming4小pg4103.cpp,该程序是一球从100米高度自由落下,每次落地 后反跳回原高度的一半:再落下,求它在第10次落地时,共经过多少米?第10次反弹多高? 请修改该程序,使其能正确运行。修改后的程序以pg4103_ok.cpp保存。源程序内容如下。 #include≥ void main(void) { float sn=100.0.hn=sn/2; -65-
图 4.1.4 程序运行状态表示 图 4.1.5 切换到数据输入窗口 数据输入结束后,切换回 VC++6.0,观察此时的变量值,如图 4.1.6 所示,grades 的值为 刚刚输入的 78,count 的值在原来随机初始值上加 1,但是这个值显然是不正确的,不能真实 的反映所统计的及格的人数。继续单步运行程序发现 grades 的值一直保持不变,只是 count 的值在变化。通过以上单步追踪运行,可以发现问题所在。 图 4.1.6 执行一次循环体后,变量值的变化情况 改正程序后的运行结果示例如图 4.1.7 所示。 图 4.1.7 pg4102_ok.cpp 的运行结果 3.打开 c:\c-programming\4\pg4103.cpp,该程序是一球从 100 米高度自由落下,每次落地 后反跳回原高度的一半;再落下,求它在第 10 次落地时,共经过多少米?第 10 次反弹多高? 请修改该程序,使其能正确运行。修改后的程序以 pg4103_ok.cpp 保存。源程序内容如下。 #include void main(void) { float sn=100.0,hn=sn/2; - 65 -
int n; for(n=2;n<=10,n+) sn=sn+2*hn; hn=hn/2; printf("the total of road is %f n",sn); printf("the tenth is%f meter\n",hn); } 了提示:如何发现问题? 编译、链接该程序后,使用工具栏上的按钮或者快捷键F10命令,启用单步运行程序, 这时调试窗口的变量观察区会自动出现,当单步运行到 for(n=2,n<=10;n+) 语句时,会发现循环体只执行 sn=sn+2*hn; 语句,而控制改变反弹高度的 hn=hn/2; 语句没有随着循环的进行而改变,如图4.1.8及4.1.9所示,从而发现问题所在。 Q上下main0 Name Value hn 50.0066 n 9 sn 166.000 Auto Locals入this7 图4.1.8n=2时hn=50 g上下main0 Name Value hn 50.0000 n 9 sn 906.806 □4 uto Locals人this☑ -66-
int n; for(n=2;n<=10;n++) sn=sn+2*hn; hn=hn/2; printf("the total of road is %f\n",sn); printf("the tenth is %f meter\n",hn); } 提示:如何发现问题? 编译、链接该程序后,使用工具栏上的 按钮或者快捷键 F10 命令,启用单步运行程序, 这时调试窗口的变量观察区会自动出现,当单步运行到 for(n=2;n<=10;n++) 语句时,会发现循环体只执行 sn=sn+2*hn; 语句,而控制改变反弹高度的 hn=hn/2; 语句没有随着循环的进行而改变,如图 4.1.8 及 4.1.9 所示,从而发现问题所在。 图 4.1.8 n=2 时 hn=50 - 66 -
图4.1.9n=9时hn=50 改正程序后的运行结果示例如图4.1.10所示。 "C:\c-programming\4\Debug\pg4103_okexe" 回☒ 共经过299.609375米 第千茨反弹g.697656米 Press any key to continue 图4.1.10pg4103ok.cpp的运行结果 4.打开c:c-programming\4pg4104.cpp,该程序是打印半径为1到10的圆的面积,若面 积超过100,则不予打印。修改程序,使之能正确运行。修改后的程序以Pg4104_ok.cp即保存。 源程序内容如下: #include void main(void) int r, float area; for(=1;r100.0) continue; printf"半径=%d,面积=%fn",I,area方 } printf("此时半径为:%dn",r } 了提示:如何发现问题? 编译、链接该程序后,使用工具栏上的按钮或者快捷键F10命令,启用单步运行程序, 观察调试窗口的变量区中变量r和area的值,会发现当area的值大于l00的时候,循环继续 执行,如图4.1.11所示。只是不再执行printf语句,从而没有输出面积大于100时的面积值。 -67-
图 4.1.9 n=9 时 hn=50 改正程序后的运行结果示例如图 4.1.10 所示。 图 4.1.10 pg4103_ok.cpp 的运行结果 4.打开 c:\c-programming\4\pg4104.cpp,该程序是打印半径为 1 到 10 的圆的面积,若面 积超过 100,则不予打印。修改程序,使之能正确运行。修改后的程序以 pg4104_ok.cpp 保存。 源程序内容如下: #include void main(void) { int r; float area; for(r=1;r100.0) continue; printf("半径=%d,面积=%f\n",r,area); } printf("此时半径为:%d\n",r); } 提示:如何发现问题? 编译、链接该程序后,使用工具栏上的 按钮或者快捷键 F10 命令,启用单步运行程序, 观察调试窗口的变量区中变量 r 和 area 的值,会发现当 area 的值大于 100 的时候,循环继续 执行,如图 4.1.11 所示。只是不再执行 printf 语句,从而没有输出面积大于 100 时的面积值。 - 67 -
盈上下main0 Name Value area 201.062 8 Auto Locals this/ 图4.1.11面积大于100时,循环继续执行 改正程序后的运行结果示例如图4.1.12所示。 "C\c-programming\4\Debug\pg4104_ok.exe" =▣x 径=1, 面积=3.141593 =2, 面积=12.566372 ▣积=28.274338 =50.265488 面积=78.539825 此时半径为:6 Press any key to continue 图4.1.12pg4104_ok.cpp的运行结果 二、程序扩展 1.打开c:lc-programming4pg4201.cpp,该程序完成1~l00之间所有奇数之和。该源程序 内容如下: #include void main(void) int i.sum=0; for(i=1:i<=100:i++) if(i%2==1)sum=sum+i; printf("和为:%d",sum; 要求:修改上面的程序,求出1~100之间能够被3整除但不能被5整除的数。修改结果 源程序以pg4201a.cpp保存。 训练要点:读懂简单的循环结构的程序,掌握如何通过or语句实现循环,以及循环体中 -68-
图 4.1.11 面积大于 100 时,循环继续执行 改正程序后的运行结果示例如图 4.1.12 所示。 图 4.1.12 pg4104_ok.cpp 的运行结果 二、程序扩展 1.打开 c:\c-programming\4\pg4201.cpp,该程序完成 1~100 之间所有奇数之和。该源程序 内容如下: #include void main(void) { int i,sum=0; for(i=1;i<=100;i++) if(i%2==1) sum=sum+i; printf("和为:%d",sum); } 要求:修改上面的程序,求出 1~100 之间能够被 3 整除但不能被 5 整除的数。修改结果 源程序以 pg4201a.cpp 保存。 训练要点:读懂简单的循环结构的程序,掌握如何通过 for 语句实现循环,以及循环体中 - 68 -