实验四_循环结构程序设计

更新时间:2023-06-05 07:16:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验四 程序设计-循环结构程序设计

4.1 实验要求与目的

1. 理解循环条件、循环体以及循环的执行过程

2. 掌握及正确使用for、while和do-while语句实现循环程序设计

3. 掌握break,continue语句正确使用

4. 掌握双循环结构的程序设计

5. 掌握相关算法(累加、素数、最值、穷举法等)

4.2 实验指导

结构化程序设计的三大结构:顺序结构、选择结构和循环结构。

在实际生活中常说重复执行某项工作多次,或重复执行某项工作,达到某种要求为止。如果需要重复执行某些操作,在程序设计就要用到循环结构。

C语言中提供了三种循环语句:for语句、while语句和do-while语句。

1. for语句是常用的一种循环语句,它的一般格式:

for (表达式1; 表达式2; 表达式3)

循环体语句

for循环语句的执行过程:

S1:计算表达式1的值;

S2:计算表达式2的值,并判断其值是真值(非0值),还是假值(0值)。若为真值,执行步骤S3,反之执行步骤S5;

S3:执行循环体语句;

S4:计算表达式3的值;返回步骤S2;

S5:结束循环(退出循环);继续执行for 语句之后的后继语句。

2. while循环语句,它的一般格式:

while ( 条件表达式 )

循环体语句

while循环语句的执行过程:

S1:计算条件表达式的值,并判断其值是真值(非0值),还是假值(0值),若为真值,执行步骤S2,否则执行步骤S4。

S2:执行循环体;

S3:返回S1;

S4:退出循环,执行while语句的后继语句。

3. do-while循环语句,它的一般格式:

do

循环体语句

while( 条件表达式 );

do-while循环语句的执行过程:

S1:执行循环体语句;

S2:计算条件表达式的值,并判断其值是真值(非0值),还是假值(0值),若为真值,返回执行步骤S1,否则执行步骤S3;

S3:退出循环,执行do-while语句的后继语句。

循环结构在程序设计时,需清楚四个部分,循环控制变量的初值、循环条件的判断、循环体语句(需要重复操作的语句)和改变循环控制变量的变化值。

【4.1】编程实现,从键盘输入10个整数,求出它们的最大数。程序文件名ex4_1.c。

分析:在上次实验,编程实现了求两个整数的最大数,现将问题扩展到20个数,算法思想是一样的。

求任意n个整数的最大(小)数的常用算法:

定义两个变量,一个变量max(min)存放最大(小)数,另一个变量a存放输入的一个整数。

S1:首先对max赋初值。通常将输入的第一个数赋给最大(小)数,即max=a(min=a); S2:输入下一个数,并赋给a;

S3:max与a进行比较,若a大于max的值,将a的值赋给max;

S4:返回S2。

依次循环(重复执行),直到20个数都一一进行了比较,max变量中最后存储的数就是最大值。

而重复进行的“工作”,就是循环结构的循环体。

解决的两个关键问题:

1.max的初值如何给定?常采用的方法是,把输入的第一个数赋给max变量。

2.采用循环结构时,如何控制循环次数?因要从10个数中求最大值,但第一数已赋给max,因此max与剩下的9个数进行比较,所以循环9次。

本题已确定了循环次数,通常采用for循环语句。

编写源程序一,程序文件名ex4_1.c。

#include<stdio.h>

void main()

{

int a,max,i;

scanf("%d",&a);

max=a; /*将输入的第一个数作为最大数*/

for(i=1;i<10;i++) /*循环9次*/

{

scanf("%d",&a); /*输入待比较的数*/

if (max<a) max=a; /*输入的数与max的值进行比较*/

}

printf("The max value is:%d\n",max);

}

输入测试数据:21 765 78 9 456 89 76 32 90 76

程序运行结果:The max value is:765

循环结构的三种循环语句可以相互转换,也就是说选择任意一种循环语句能实现的循环结构,同样可以用其余两种循环语句实现。即用for语句可以实现的循环,用while或do-while同样可以实现。当给定了循环次数,首选for循环语句,若循环次数不明确,需要通过某条件控制循环时,首选while或do-while循环语句。while语句与do-while语句的区别是,while是先判断,后执行,而do-while是先执行,后判断。

编写源程序二,程序文件名ex4_11.c。

#include<stdio.h>

void main()

{

int a,max,i;

scanf("%d",&a);

max=a; /*将输入的第一个数作为最大数*/

i=2; /*前面已经输入过一个数,因此i的初值从2开始*/ while (i<=10) /*循环9次*/

{

scanf("%d",&a);

if (max<a) max=a;

i++; /*i为循环控制变量,统计输入数的个数*/

}

printf("The max value is:%d\n",max);

}

编写源程序三,程序文件名ex4_12.c:

#include<stdio.h>

void main()

{

int a,max,i;

scanf("%d",&a);

max=a;

i=2;

do

{

scanf("%d",&a);

if (max<a) max=a;

i++;

}

while (i<=10);

printf("The max value is:%d\n",max);

}

小结:

1. 无论选择哪种循环语句,循环体若由两条以上的语句,必须用花括号括起来,组成一条复合语句。C程序约定,循环体默认只有一条语句。

2. 无论何种循环语句,其执行特点是:循环条件为真,继续执行循环体,循环条件为假,退出循环。

【4.2】编程实现,判断一个正整数是否是素数,若是输出“YES”,否则输出“No”。程序文件名ex4_2.c 。

分析:所谓素数(质数)就是除1和它本身之外没有其他因子的数。换句话说只能被 1和它本身整除的数就是素数(质数)。

判断一个数是否是素数,可分两步实现:

第1步,逐一验证除1和它本身之外数能否整除该数。若该数为m,则验证从2开始至m-1为止的所有数能否整除该数。

第2步,得出结论。由第1步可知若其中有一个数能整除该数,则该数不是素数,否则是素数。

将问题的所有可能的情况逐一验证,直到找到解或将全部可能的情况都测试为止的算法,称为穷举法。穷举法是程序设计中常用的算法之一。穷举算法特点是算法简单,但运行时所花费的时间量大。

穷举法在程序设计中,主要采用循环语句和选择语句,循环语句用于控制穷举所有可能的情况,也可以说是对所有可能进行验证的范围,而选择语句判断当前设定的条件是否满足的状态解。

采用穷举法编程实现判断整数m是否是素数。程序设计的循环语句控制验证范围,1到m-1。选择语句的条件就是判断该数能否被1到m-1的数整除,若验证有一个数能整除该数,就立刻中断循环退出验证过程。

由此循环语句退出,一种可能是所有的可能都验证完退出,即从2到m-1的所有数都验证完,没有一个数能整除数m,其结论是数m是素数;另一种可能是其中一个数能整除该数,则循环语句中断退出,其结论是数m不是素数。

#include <stdio.h>

void main( )

{

int m,i;

printf("Please enter a integer\n");

scanf("%d",&m);

for(i=2;i<=m-1;i++)

if(m%i==0) break;

if(i<m) printf("NO\n");

else printf("YES\n");

}

第一次运行程序:

输入测试数据:23

程序运行结果:YES

第二次运行程序:

输入测试数据:145

程序运行结果:NO

小结:

1. 验证m是否是素数的范围:2到m-1或2到m/2或2到m。

2. 在验证过程中,当有一个数能整除数m,则其后的数就不必验证,可由break语句

中断该循环。

3. break 语句只能用在switch语句和循环语句,在循环语句中使用break语句时,通

常和if语句连用,其含义是满足某个条件时,退出循环。

4. 当循环退出时,循环控制变量i的值,决定了数m到底是不是素数。当i<m时,说

明执行循环体时由break语句中断而退出循环,即m能被i整除,m不是素数,反之,当i>=m时,m是素数。

5. 选择结构if-else可以有多种变数,程序并非唯一的。

如,if-else也可修改为:

if(i>=m) printf("YES\n");

else printf("NO\n");

【4.3】编程实现:计算并输出n(包括n)以内能被5或9整除的所有自然数的倒数之和。程序文件名ex4_3.c。

分析:本程序的关键问题求和,则采用累加算法,该算法采用循环结构。

算法思想,引入一个和变量sum,一个加数变量b,求和表达式为,sum=sum+b; 累加算法就是重复执行求和表达式sum=sum+b的过程。细化问题,该求和表达式要执行多少次,或满足何条件就不再执行;每次执行时b如何变化。

具体问题具体分析。由题意,求自然数的倒数之和,倒数可考虑为1/i。循环次数为n。 #include <stdio.h>

void main( )

{

int i,n;

float sum=0.0;

scanf("%d",&n);

for(i=1;i<=n;i++)

if(i%5==0||i%9==0)

sum+=1.0/i;

printf("%f ",sum);

}

输入测试数据:20

程序运行结果:s=0.583333

小结:

1. 求满足能被5或9整除的所有自然数的条件表达式:i%5==0||i%9==0

2. 求分数之和时,一定要考虑整型除整型的情况。源程序中变量i为整型,所以倒数1/i,在具体编程时可处理为1.0/i或1/(float)i的形式。

【4.4】编程实现,计算 n!的值。程序文件名:ex4_4.c。

n 110

分析:原题为求1+2!+ +10!。程序设计的核心是累加。观察第n-1项与第n项,可知第n-1项与第n项的关系为:n!=(n-1)!*n。由此该程序设计,可采用递推算法。

递推算法是计算机数值计算中的一个重要算法,算法思想是给定一个已知条件,根据前后项的关系,由前项推后项。

假设变量t表示项,t的初始值为1,则第n项的表达式为: t=t*n。

递推算法,采用循环语句。

#include <stdio.h>

void main()

{

long i,n,sum=0,t=1;

for(i=1;i<=10;i++)

{

t=t*i;

sum=sum+t;

}

printf("1!+2!+...+l0!=%ld",n,sum);

}

程序运行结果:1!+2!+...+10!=4037913

小结:

1. 由于求阶乘的整数值比较大,所以数据类型常用长整型。

2. 采用递推算法时,一定有注意初始值的给定。

【4.5】编程实现,从键盘输入任意一串字符,以回车键结束。该字符串中的字符若是小写字母转换为大写字母,若是大写字母转换为小写字母,其它字符原样输出。程序文件名ex4_5.c。

分析:本题的关键问题之一,如何判断一个字符是小写字母还是大写字母,或者是数值字符等。

关键问题之二,如何实现大小写字母的转换。

关键问题之三,如何用getchar() 实现从键盘输入任意一串字符。

前两个问题在实验三中已谈过,本次实验解决问题三。字符输入函数getchar()每次只能输入一个字符,换句话,每次只能从键盘接收一个字符,若要接收一串字符,需采用循环语句。

如何来确定循环条件表达式呢?

当题中没有明确给定时,以字符输入函数getchar()接收回车符('\n')作为循环结束条件。 #include "stdio.h"

void main()

{ char c;

while((c=getchar())!='\n' )

{ if(c>='a'&&c<='z')

c=c-32;

else

if(c>='A'&&c<='Z')

c=c+32;

putchar (c);

}

}

输入测试数据:ABCd#$GTabc23

程序运行结果:abcD#$gtABC23

小结:

1. 循环条件表达式 (c=getchar())!='\n',依据运算符的优先级,圆括号最优先,先运算c=getchar() ,从键盘上接收一个字符,赋予变量 c,然后再判断变量 c的值是否不等于'\n',若是条件为真,执行循环体,否则退出循环。

2. 循环条件表达式若修改为:c=getchar()!='\n',关系运算符优先赋值运算符,首先计算getchar()!='\n',即当从键盘接收的一个字符不等于回车符,返回值1,然后将1赋给字符

变量c,数值既不是大写字母也不是小写字母,所以直接执行putchar (c);输出ASCII码为1

。当从键盘是接收的字符是回车符时,返回值0,条件为假,退出循环。

3. 若本题改为,从键盘输入任意一串字符,以’#’号键结束时,while循环的循环条件表达式可修改为: (c=getchar())!='#' 。

【4.6】编程实现,利用循环嵌套在屏幕上显示如下图形。程序文件名ex4_6.c。

分析:打印图形的程序设计的算法是将图形看作是由行和列组成字符图案,采用双循环结构,外循环控制图形的行数,内循环控制每一行输出的字符。该图形总共7行,第一行看上去只的一个“*”,但输出时先要输出6个空格,再输出1个“*”,第二行先输出5个空格,再输出3个“*”,依次规律输出每行的字符。

每行应由两种字符组成的图案,一个字符是空格,一个字符是星号。因此,内循环采用两个并行循环,第一个循环控制每行空格输出的个数,第二个循环控制每行“*”输出的个数。

由于每行的空格个数和“*”号数都不一样,因此内循环次数不是一个固定值,根据每行空格或“*”个数的规律设置内循环的循环条件。若以第七行第一个“*”为坐标原点,则每行上空格的个数变化可设置为k<6-i。用变量i表示行数,用变量j表示每行上打印“*”的个数,则每行上“*”的个数变化可设置j<2*i+1。

#include <stdio.h>

void main()

{

int i,j,k;

for (i=0;i<7;i++) /*外循环控制图形的行数*/

{

for (k=0;k<6-i;k++) /*循环控制每行的空格数*/

printf(" ");

for (j=0;j<2*i+1;j++) /*循环控制每行的星号个数*/

printf("*");

printf("\n"); /*每输完一行图形字符须换行*/

}

}

小结:

1. 通常情况下图形打印采用双循环结构。外循环控制图形的行数,内循环控制每行的字符个数。内循环的循环次数不是一个固定值,一般需要找出循环次数与外层循环控制变量之间的关系,以便确定内层循环的次数。

2. 外循环的循环体的最后一条语句通常是printf("\n"); 语句,控制每行的换行。

3. 本程序使用了三个循环结构,其中第一个循环和第二、第三个循环是嵌套关系,而第二与第三个循环之间是并列关系。 循环嵌套编程时,内外循环的循环控制变量必须不相同,否则会出错。但并行循环时循环控制变量可以相同,互不干涉。

4.3 实验内容

4.3.1 夯实基础

【4.7】编程实现,从键盘上输入10个学生的成绩,求平均成绩、最高分和最低分。程序文件名ex4_7.c。

输入测试数据:34 56 87 90 87 65 78 87 96 69

程序运行结果:max=96 min=34 avg=74.90

【4.8】编程实现,求 k k k 。程序文件名ex4_8.c。 2

k 1k 1k 110050101

程序的运行结果为 47977.928968

【4.9】编程实现,计算

s 程序文件名ex4_9.c。【提示,在C语言中可调用log(n)求ln(n)。】

输入测试数据:20

程序的运行结果为 6.506583

n个a

【4.10】编程实现,求s a aa aaa aa a的值,其中a是一个数字。例如当a为2,n为5时,计算,2+22+222+2222+22222的值。【要求,a和n的值由键盘输入。提示,可采用递推算法。】程序文件名ex4_10.c。

输入测试数据:8 10 (其中a=8,n=10)

程序运行结果:1286608608

【4.11】编程实现,输入一行字符,分别统计出其中英文字母,空格,数字和其它字符的个数。程序文件名:ex4_11.c。

输入测试数据:abcd !@# 123 EFG 890 *&^

程序运行结果:英文字符的个数:7,空格的个数:5,

数字字符的个数:6,其它字符的个数:6

【4.12】编程实现,求2~100间的所有素数。程序文件名ex4_12.c。

程序运行结果: 2 3 5 7 11

13 17 19 23 29

31 37 41 43 47

53 59 61 67 71

73 79 83 89 97

【4.13】编程实现,利用双循环编程,输出下列所示的图形。程序文件名ex4_13.c。

4.3.2 应用提高

【4.14】程序填空题。程序实现的功能是译密码。为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。请填空,填空时不得增行或删行,也不得更改程序的结构,一条横线上只能填写一条语句!程序文件名ex4_14.c。

例如,可以按如下规律将电文变成密码:将字母A变成字母E,a变成e,即变成其后的第4个字母,W变成A,X变成B,Y变成C,Z变成D。字母按上述规律转换,非字母字符不变。

输入测试数据:Welcome to the country!

程序运行结果:Aipgsqi xs xli gsyrxvc!

#include <Stdio.h>

void main()

{

char c;

while((c=getchar())!='\n')

{

if((c>='a' && c<='z') || (c>='A' && c<='Z'))

{

_______【1】__________;

if(c>'z'||c>'Z' && c<='Z'+4 )

_______【2】_________;

}

printf("%c",c);

}

}

【4.15】程序填空题。程序实现的功能中是,对任意整数,将其各位上为偶数的数取出,并按原来从高位到低位相反的顺序组成一个新的数。请填空,填空时不得增行或删行,也不得更改程序的结构,一条横线上只能填写一条语句!程序文件名ex4_15.c。

输入测试数据:27638496

程序运行结果:64862

#include <stdio.h>

{ long n,x=0;

int i,t;

do{

printf("Please input(0<n<1000000000): ");

scanf("%ld",&n); }

while(n>99999999||n<0);

while(n!=0)

{ t=n%10;

if(_____【1】________)

x=10*x+t;

_____【2】_______;

}

printf("\nThe result is: %ld\n",x);

}

4.4 实验思考

【思考1】阅读下列程序,写出其程序运行结果。

#include<stdio.h>

void main()

{ int y=10,i;

for(i=0;i<3;i++);

--y;

printf("%d\n",y--);

}

程序运行结果:

【思考2】阅读下列程序,写出其程序运行结果。

#include <stdio.h>

void main()

{

int a=0,n=3;

while (n--)

printf("%d ",a++*2);

}

程序运行结果:

【思考3】阅读下列程序,下列程序能否正常运行,若能,写出程序运行结果,若不能,修改此程序,并写出修改后其程序运行结果。

#include <stdio.h>

void main()

{

for(n=10,n<=20,n++) {

if(n%3==0) m++; }

printf("%d",m); }

本文来源:https://www.bwwdw.com/article/mse1.html

Top