第五章-循环结构程序设计

5.1 while循环语句
特点:先判断表达式,后执行语句。
格式:
  while(表达式)
  语句;(循环体)
说明:
(1)while 后一对圆括号中的表达式可以是 C 语言中任意合法的表达式,但不能为空,由它来控制循环体是否执行。
(2)因为 while 循环语句是当型循环结构,所以循环体有可能一次也不执行。
(3)循环体可以是任何语句,但应有使循环趋于结束的语句
(4)重复执行的语句被称为循环体,表达式被称为循环表达式
注意:
(1)循环体如果包含一个以上的语句,应该用花括弧{}括起来,以复合语句形式出现。
(2)如果循环体不是空语句,则while的括号后面不加分号
5.2 do…while循环语句
特点:先执行,后判断。
格式:
  do
   语句;(循环体)
  while(表达式);
注意:while最后的分号不要漏掉!
说明:
(1)因为 do…while 循环语句是先执行,后判断,所以循环体至少执行一次
(2)循环体可以是任何语句,但应有使循环趋于结束的语句
(3)在一般情况下,用 while 语句和 do…while 语句处理同一问题时,若二者的循环体部分是一样的,则它们的结果也一样
5.3 for循环语句
格式:
  for(表达式1;表达式2;表达式3)语句;
执行顺序:
  先计算表达式 1,接着计算表达式 2,若表达式 2 的值为非 0,则执行循环体;然后计算表达式 3,再计算表达式 2。若表达式 2 的值仍为非 0,则继续执行循环体,否则退出循环。
说明:当表达式 1 或表达式 2 省略时,其后的分号不能省略。

  • 表达式1省略,应在for之前对循环变量赋初值
  • 表达式2省略,则不判断条件,循环无终止进行下去,则应另设法保证循环的结束
  • 表达式3省略,则应将循环变量的增减放在循环内

注意:若循环体不是空语句,不能在 for 语句的圆括号后加分号。
5.4 循环的嵌套
说明:
(1)嵌套的循环控制变量一般不应同名,以免造成混乱。
(2)循环嵌套要注意正确地使用缩进式书写格式来明确循环嵌套的层次关系,以增加程序的可读性
(3)外层循环应完全包含内层循环,不能发生交叉
【例5.8】在1~5中取出3个互不相同的整型数,输出其和能被4整除的个数。
穷举法

#include"stdio.h"
int main(void)
{
	int i,j,k,n = 0;
	for(i=1;i<=5;i++)
		for(j=i+1;j<=5;j++)
			for(k=j+1;k<=5;k++)
				if((i + j + k) % 4 == 0)
					{
						n++;
						printf("i=%d,j=%d,k=%d\n",i,j,k);
					} 
	printf("n=%d",n);
}

学习:利用三重for循环来提取数字,且保证数字不重(从第一个到最后一个,依次提取)(如果需要重复,则把三个循环的变量(i,j,k)的初始值都变为1)
5.5 循环的退出
5.5.1 break 语句
功能:执行break语句,结束整个包含它的最内层循环
说明:
(1)break 语句只能用于 switch 语句或循环语句中。
(2)在嵌套的循环结构中使用时,break 语句只能跳出包含它的最内层循环,不能同时跳出多层循环。
(3)switch中的break:终止其所在的switch语句。
5.5.2 continue 语句
功能:结束本次循环,即跳过循环体中下面尚未执行的语句,接着继续下一次是否执行循环体的判定。
说明:
(1)continue 语句只能用于循环语句中
(2)continue 语句和 break 语句都实现了程序执行方向上的无条件转移,但是 continue 语句只结束本次循环,而不是终止整个循环的执行;break 语句则是结束整个循环过程,不再判断执行循环的条件是否成立。
5.6 用goto语句构成循环
格式:goto 语句标号;
说明:
(1)语句标号是用标识符表示,它的命名规则与变量名相同。例如,“goto loop;”是合法的。
(2)goto 语句和 if 语句配合使用,可实现循环功能。
(3)结构化程序设计方法主张限制使用 goto 语句,因为滥用 goto 语句将会影响程序结构的清晰,降低可读性。
5.7 循环结构程序设计举例
【例5.14】求1~100之间的全部素数。
分析:可先求出数m的平方根k,然后让数m被2到k除。

#include<stdio.h>
#include<math.h>
int main(void)
{
	int k,m,i,n = 0;
	for(m=1;m<=100;m=m+2)
		{
			k = sqrt(m);		//求平方根
			for(i=2;i<=k;i++)
			{
				if(m % i == 0)
					break;
			}
			if(i > k)
			{
				printf("%-4d",m);
				n++;			//判断是否是正常退出循环,为真,则m是素数,输出并计数
			}
			if(n % 10 == 0printf("\n");	//判断一行是否输出了10个素数,若是,换行	
		}
	printf("\nn=%d",n);
}

补充:因为a/b=c,同理a/c=b。所以只需开根号,求一半,以减少运算量。
【例5.15】将原文转换为密文。通常在互联网上传送信息时,为保证安全,发送者先按一定的规律将原文转换为密文,然后发送给接收者,接收者收到密文后,再将密文按约定的规律译回原文。例如,转换规律为:字母转换为其后第 6 个字母,非字母不变。
分析:
(1)先判断该字符是否是大写字母或者是小写字母,若是,则将其值加 6(变成其后的第 6 个字母)。
(2)若加 6 之后字符值大于’Z’或’z’,则表示原来的字母在’T’或’t’之后,应按图 5-11 所示的规律将它转换为’A’~’F’(或’a’~’f')之一。方法是使其减 26。
类似于补码的计算,减去模

#include<stdio.h>
int main(void)
{
	char ch;
	while((ch = getchar()) != '\n')
		{
			if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
				{
					ch = ch + 6;
					if(ch >= 'Z' || ch >= 'z')		//只有离Z最近的5个大写字母以及离z最近的5个小写字母才需要考虑减去26
						ch = ch - 26;
				}
			printf("%c",ch);
		}	
}

【例5.16】百马百瓦问题。有 100 匹马,驮 100 块瓦,大马驮 3 块,小马驮 2 块,两个马驹驮 1 块。问大马、小马、马驹各多少?编程列出所有可能的驮瓦方案。
分析:
  设大马、小马、马驹各为 x、y、z 只,根据题目要求,可以用下列方程表示:
         x+y+z=100
         3x+2y+z/2=100
采用方法:穷举法

#include<stdio.h>
int main(void)
{
	int x,y,z;
	for(z=98;z>=2;z=z-2)
		for(y=50;y>=1;y--)
			for(x=0;x<=33;x++)	//人为限制起始条件,可以减小计算量。
				if(x + y + z == 100 && 3*x +2*y + z/2 == 100)
					printf("x=%2d,y=%2d,z=%2d",x,y,z);
}

【例5.17】小猴吃桃问题。有一天小猴摘下了若干个桃子,当即吃掉一半,还不过瘾,又多吃了一个;第二天接着吃了剩下的桃子的一半后又多吃一个;以后每天都吃尚存桃子的一半零一个,
到第 10 天早上要吃时只剩下一个了。问小猴第一天共摘下了多少个挑子?
分析:“递推问题”
设第 n 天的桃子为 x,它是 n-1 天的桃子数的一半减 l 个,即:xn=0.5*x(n-1)-1,那么 n-1 天的桃子数为:x(n-1)=(xn+1)×2

#include<stdio.h>
int main(void)
{
	int i,x;
	x = 1;	//第十天的桃子数
	for(i=9;i>=1;i--)
		{
			x = (x + 1) * 2;
			printf("i=%2d,x=%d\n",i,x);	//第i天的桃子数为x只
		}
}

【例5.18】用迭代法求某数 a 的平方根。已知求平方根的迭代公式为:x(n+1)=(xn+a/xn)/2
分析:利用以上迭代公式求 a 的平方根的算法步骤如下。
(1)设定一个值给 x0作为初值,这里取 a/2 作为 x0的初值,利用迭代公式 x1=(x0+a/x0)/2,求出一个 x1。
(2)把新求得的 x1的值赋给 x0,用此新的 x0再求出一个新的 x1。
(3)如此重复步骤(2),直到前后两次求出的 x0和 x1满足以下关系:|x1-x0|<10^-6。
(4)输出 a 的平方根的值,即 x1的值。

#include<stdio.h>
#include<math.h>
int main(void)
{
	float a,x0,x1;
	printf("Iuput a :\n");
	scanf("%f",&a);
	if(a < 0)
		printf("Input error!\n");	//不能求负数的平方根
	else
		{
			x0 = a / 2;
			x1 = (x0 + a / x0) / 2;
			do
			{
				x0 = x1;
				x1 = (x0 + a / x0) / 2;
			}while(fabs(x0 - x1) < 1e-6);	//当计算值小于误差时停止
			printf("sqrt(%f)=%f,标准sqrt(%f)=%f\n",a,x1,a,sqrt(a));
		}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值