5.1 为什么需要循环控制

前面介绍了程序中常用到的顺序结构和选择结构,但是只有这两种结构是不够的,还需要用到循环结构(或称重复结构)。因为在程序所处理的问题中常常遇到需要重复处理的问题。

循环结构和顺序结构、选择结构是结构化程序设计的3中基本结构。

5.2 用while语句实现循环

while语句先判断是否符合条件,若符合,则执行while后面的语句(称为循环体)。

while语句的一般形式如下:

while(表达式)语句

其中的“语句”就是循环体。循环体可以是一句语句,也能是复合语句(用花括号括起来的若干条语句)。执行循环体的次数是由循环条件控制的,这个村换条件就是上面一般形式的”表达式”,它称为循环条件表达式,当表达式的值为“true”(以非0值表示),就执行循环体语句,为“false”(以0表示),就不执行循环体结构。

while语句可简单地记为:只要当循环条件表达式为真(即给定的条件成立),就执行循环体语句。

注意:while循环的特点是:先判断条件表达式,后执行循环体语句。

例:求1+2+3+……+100

编写程序:

 #include <stdio.h>
int main()
{
int I = , sum = ;
while(i<=)
{
sum += i;
i++;
}
printf(“sum=%d\n”,sum);
return ;
}
 运行结果:sum=

code result

循环分析:

(1)循环体如果包含一个以上的语句,应该用花括号括起来,作为复合语句出现。如果不加花括号,则while语句的范围只到while后面的第1个分号处。如,本例中while语句中如雾化括弧啊,则while语句范围只到“sum += I;”编程死循环

(2)不要忽略给i和sum赋赋值(这是未进行累加前的初始情况),否则它们的值是不可预测的,结果显然不正确。可上机测试看看

(3)在循环体中应有使循环趋向于结束的语句。如,本例中使用i++;语句来达到此目的。

5.3 用do……while语句实现循环

除了while语句以外,C语言还提供了do……while语句来实现循环结构。如:

int I = 1;

do{

printf(“%d”,i++);

}while(i<=100);

它的作用是:执行(do表示“做”)printf语句,然后检查i的值,当i小于或等于100时,就返回执行循环体(printf语句),直至i大于100为止。也可写成

do

printf(“%d”,i++);

while(i<=100);

为了使程序清晰、易读,简易把循环体用花括号括起来。

do……while语句的执行过程是:先执行循环体,然后再检查条件是否成立,若成立,再执行循环体。这是和while语句是不同的。

注意:do……while语句的特点是:先无条件地执行循环体,然后判断循环条件是否成立。

do……while语句的一般形式为

do

语句

while(表达式);

其中的“语句”就是循环体。

过程:先执行一次循环体语句,然后再判别表达式,当表达式的值为“true”(以非0值表示),就执行循环体语句,为“false”(以0表示),就不执行循环体结构。

例:while和do……while循环的比较

(1)用while循环

 #include <stdio.h>
int main()
{
int i , sum = ;
printf(“please enter i=\n”);
scanf("%d",&i);
printf(“%d\n”,i);
while(i<=)
{
sum += i;
i++;
}
printf(“sum=%d\n”,sum);
return ;
}

while

运行的结果为:please enter i=100

sum = 100

(2)用do……while循环

 #include <stdio.h>
int main()
{
int i , sum = ;
printf(“please enter i=”);
scanf("%d",&i);
printf(“%d\n”,i);
do
{
sum += i;
i++;
}while(i<=)
printf(“sum=%d\n”,sum);
return ;
}

do…while

运行的结果为:please enter i=100

sum = 201

两者的区别:对while循环来说,一次也不执行循环体(表达式“i<=10”的值为假),而对do……while循环语句来说则至少要执行一次循环体。结论:当while后面的表达式的第1次的值为“真”时,两种循环得到的结果相同;否则,二者结果不相同(指二者具有相同的循环体的情况)。

5.4 用for语句实现循环

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

         语句

3个表达式的主要作用是:

表达式1:设置初始条件,只执行一次。可以为零个、一个或多个变量设置初值。

表达式2:是循环条件表达式,用来判断是否继续循环。在每次执行循环体前先执行此表达式,决定是否继续执行循环。

表达式3:作为循环的调整,例如使循环变量增值,它是在执行完循环体后才进行的。

这样,for语句就可以理解为

for(循环变量赋初值;循环条件;循环变量增值)

语句

例:

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

sum += I;

for语句执行的过程如下:

(1)先求解表达式1.把整数1赋给变量i

(2)求解表达式2,若此条件表达式的值为真(非0),则执行for语句中循环体,然后执行第(3)步。若为假,转到第5步

(3)求解表达式3.

(4)转回步骤(2)继续执行

(5)循环结束,执行for语句下面的一个语句

for执行过程与下面一致

i = 1;

while(i<=100)

{

sum = sum+i;

i++;

}

显然,用for语句简单、方便

说明:

(1)for语句的一般形式

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

可以改写成while循环的形式:

表达式1;

while (表达式2)

{

         语句

         表达式3

}

二者无条件等价。

(2)“表达式1”可以省略,即不设置初值,但“表达式1”后的分号不能省略。如:

for(;i<=100;i++) sum = sum +i;

注意:由于省略了“表达式1”,没有对循环变量赋初值;因此,为了能正常执行循环,应该在for语句之前给循环变量赋以初值。

(3)“表达式2”也可以省略,即不用“表达式2”来作为循环条件表达式,不设置和检查循环的条件。如:

for(i=1;;i++) sum = sum +i;

此时循环无终止地执行下去,相当于

i = 1;

while(1)

{

sum = sum+I;

i++;

}

(4)表达式3可以省略,但此时程序设计者应另外设法保证循环能正常结束。

for(i=1;i<=100;)

{

sum = sum +i;

i++;

}

(5)如果表达式1和表达式3都没有,只有表达式2,即只给循环条件,情况会怎么样?如:

for(;i<=100;)

{

sum = sum +i;

i++;

}

应当在for语句前给循环变量赋初值,否则循环无法正常进行;即

i = 1;

for(;i<=100;)

{

sum = sum +i;

i++;

}

相当于:
i = 1;

while(i<=100)

{

sum
= sum + i;

i++;

}

(6)甚至可以将3个表达式都可省略,如:

for(;;)

{

sum = sum +i;

i++;

}

相当于

while(1)

{

sum
= sum + i;

i++;

}

当然,这是没有实用价值的,只是用于学习这种写法也是可以的。

(7)表达式1可以设置循环变量初值的赋值表达式,也可以是与循环变量无关的其他表达式。如:

for(sum=0;i<=100;i++) sum = sum + i;

(8)表达式1和表达式3可以是一个简单的表达式,也可是逗号表达式,即包含一个以上的简单表达式,中间用逗号间隔。

for(sum=0,i=1 ; i<=100 ; i++) sum = sum
+ i;

for(i=0, j=100;i<=100;i++,j--) k = i+j;

在逗号表达式内按自左向右顺序求解,整个逗号表达式的值为最后边的表达式的值。如:

for(i=1;i<=100;i++,i++) sum = sum + i;

等价于

for(i=1;i<=100;i=i+2) sum = sum +i;

(9)表达式2一般是关系表达式(如i<=100)或逻辑表达式(如a<b&&x<y),但也可是数值表达式或字符表达式,只要其值为非零,就执行循环体。如:

for(i = 0; (c = getchar())!=’\n’;i+=c);

注意:此for语句的循环体为空语句,把本来要在循环体内处理的内容放在表达式3中,作用是一样的。

(10)C99允许在for语句的“表达式1”中定义标量并赋初值,如:

for(int i=1;i<=100;i++) sum = sum + i;

5.5 循环的嵌套

一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。内嵌的循环中还可以嵌套循环,这就是多层循环。

3种循环(while循环、fo…while循环、for循环)可以相互嵌套。下面是合法的格式:

(1)
while ()
{   ……
  while()//内层循环
  {……}
}
(2)
do
{
  ……
  do
  {
    ……
  }while ();//内层循环
}while ();

(3)
for(;;)
{
  for(;;)//内层循环
  {……}
}
(4)
while()
{
  ……
  do
  {  
    ……
  }while ();//内层循环
……
}

(5)
for(;;)
{
  ……
  while()//内层循环
  {
    ……
  }
  ……
}

(6)
do
{
  ……
  for(;;)//内层循环
  {……}
}while ();

5.6几种循环的比较

(1)3中循环都可以用来处理同一问题,一般情况下它们可以相互代替。

(2)在while循环和do…while循环中,只在while后面的括号内指定循环条件,因此为了使循环能正常结束,应在循环体中包含使循环趋于结束的语句(如i++或i+=1等)

for循环可以在表达式3中包含使循环趋于结束的操作,甚至可以将循环体中的操作全部放到表达式3中。因此for循环的功能更强,凡是用while循环能完成的,for循环也能胜任。

(3)用while和do…while循环时,循环变量初始化的操作应在while和do…while语句之前完成。而for语句可以在表达式1实现循环变量的初始化。

(4)while循环、do…while循环、for循环,都可以用break语句跳出循环,用continue语句结束本次循环(break语句和continue语句见后面)

5.7 改变循环执行的状态

5.7.1
用break语句提前结束循环。

例:当sum大于或等于1000时循环结束

 //break语句的使用
#include <stdio.h>
int main()
{
int sum = ;
int i = ;
for(;i<=;i++)
{
if(sum>=) //如果sum>1000提前结束循环
break;
sum += i;
}
printf("循环的次数为:%d,sum的值为:%d\n",i,sum);
return ;
}

break Code

break语句的一般形式:

break

其作用是使流程跳到循环体之外,接着执行循环体下面的语句。

注意:break语句只能用于循环语句和switch语句之中,而不能单独使用。

5.7.2 用continue语句提前结束本次循环

有时并不希望终止整个循环的操作,而只希望提前结束本次循环,而接着执行下次循环。这种情况可以使用continue语句

例:要求输出1~100能被3和5同时整除的数

 #include <stdio.h>
int main()
{
int i=;
int j=; //用®?于®¨²换?行D
for(;i<=;i++)
{
if(i%==&&i%==)
{
j++;
printf("%d\t",i);
if(j%==)
printf("\n");
}
}
printf("\n");
return ;
}

continue Code

continue语句的一般形式为

continue;

其作用为结束本次循环,即跳过循环体中下面尚未执行的语句,转到执行体结束点之前,接着执行for语句中的“表达式3”,然后进行下一次是否执行循环的判断。

5.7.3 break语句和continue语句的区别

continue语句只结束本次循环,而不是终止整个循环的执行。而break语句则是结束整个循环过程,不在判断执行循环的条件是否成立。如,下列两种循环结构:

(1)while(表达式1)

{

……

if(表达式2) break;

……

}

(2)while(表达式1)

{

……

if(表达式2) continue;

……

}

例:通过下列对照,比较break语句和continue的区别

 #include <stdio.h>
int main()
{
int i,j,n=;
for(i=;i<=;i++)
{
for(j=;j<=;j++,n++)
{
if(n%==)
printf("\n");
if(i==&&j==)break;
printf("%d\t",i*j);
}
}
printf("\n");
printf("\n");
printf("\n");
for(i=;i<=;i++)
{
for(j=;j<=;j++,n++)
{
if(n%==)
printf("\n");
if(i==&&j==)continue;
printf("%d\t",i*j);
}
}
return ;
}

break And continue

5.8循环程序的举例

例:fibonacci数列的前40个数。这个数列有如下特点:第1,2两个数为1,1,从第3个数开始,该数是其前面两个数之和。即:

F1 = 1                (n=1)

F2 = 1                (n=2)

Fn = Fn-1 +Fn-2 (n>=3)

当然,这个数列有另一个故事,那就是兔子繁殖的问题;有一堆兔子,有1对兔子,从出生后第三个月起每个月都生1对兔子 ,小兔子长到第三个月后每个月又生1对兔子,假如兔子都不死 ,问每个月的兔子总数为多少?

解题思路:最简单易懂的方法就是,根据题意,从前2个月的兔子数可以推出第3个月的兔子数。设第1个月的兔子数为f1 = 1,第2个月的兔子数f2 = 1,则第3个月的兔子数f3 = f1+f2.然后第4个月就是 f4 = f3 +f2.当然,我们不是手动去写出相加40项,用循环即可。

编写程序:

 //求Fibonacci数列前40项
#include <stdio.h>
int main(){
long int f1,f2;
int i;
f1 = ; f2 = ; //赋初始值
for(i = ;i<=;i++){//循环20次,一次两个,结果为前40项
printf("%12d%12d",f1,f2);//输出 两项
f1=f1+f2;f2=f2+f1;//计算下面两项
if(i % == ) //一行四个 好看用
printf("\n");
}
return ;
}

程序分析:程序共应输出40个月的兔子数。为了能更好的容纳兔子数量,所以应该定义为long int型。我们在循环体中一次求出下两个月的兔子数。且用f1和f2两个变量即可。

第5章 简单的C程序设计——循环结构程序设计的更多相关文章

  1. 【C语言】第5章 循环结构程序设计

    第5章 循环结构程序设计 三种基本循环控制结构 使用while语句实现循环 先判断条件表达式,后执行循环体语句 while (循环条件表达式) { 循环体 } 用do-while语句实现循环 先无条件 ...

  2. 160809209_李梦鑫_C语言程序设计实验3 循环结构程序设计

    <C语言程序设计>实验报告 学 号 160809209 姓 名 李梦鑫 专业.班 计科16-2班 学    期 2016-2017 第1学期 指导教师 黄俊莲 吉吉老师 实验地点 C05 ...

  3. Python程序设计实验报告四:循环结构程序设计(设计型实验)

    安徽工程大学 Python程序设计 实验报告 班级   物流191   姓名  姚彩琴  学号3190505129 成绩 日期     2020.4.8     指导老师       修宇 [实验名称 ...

  4. 算法竞赛入门经典_第二章:循环结构程序设计_上机练习_MyAnswer

    习题2-1 位数 输入一个不超过109的正整数,输出它的位数.例如12735的位数是5.请不要使用任何数学函数,只用四则运算和循环语句实现. #include<stdio.h> int m ...

  5. 第4章 简单的C程序设计——选择结构程序设计

    在顺序结构中,各语句是按自上而下的顺序执行的,执行完上一个语句就自动执行下一个语句,是无条件的,不必作任何判断.实际上,很多情况下,需要根据某个条件是否满足来决定是否执行指定的操作任务,或者从给定的两 ...

  6. C++第4次实验(基础班)—循环结构程序设计

    此次上机中的4个题目项目6.项目7(选1)必做.其他2两题可从剩下的项目中选,也可从项目7中选. [项目1:利用循环求和]求1000以内全部偶数的和(答案:250500) 要求:请编出3个程序来,分别 ...

  7. 160809228_符瑞艺_C语言程序设计实验3 循环结构程序设计

      #include <stdio.h> int main(){ //使用for循环完成1+2+......+100 ; ;i<=;i++) sum +=i; //sum = sum ...

  8. Java程序设计基础笔记 • 【第5章 循环结构】

    全部章节   >>>> 本章目录 5.1 while循环结构 5.1.1 循环简介 5.1.2 while循环 5.1.3 while循环的使用 5.1.4 while循环的注 ...

  9. 全国计算机等级考试二级教程-C语言程序设计_第5章_循环结构

    for循环结构的嵌套 外层循环每循环一次,内层循环会完整循环一次. 外层循环是竖. 内层循环是横. for, do...while, while的选择: 如果有固定次数,如阶乘! ,判断素数,用 fo ...

随机推荐

  1. [ Java面试题 ]数据库篇

    基本表结构: student(sno,sname,sage,ssex)学生表 course(cno,cname,tno) 课程表 sc(sno,cno,score) 成绩表 teacher(tno,t ...

  2. 1.1 为什么要使用lambda 表达式

    第1章 lambda 表达式 1.1 为什么要使用lambda 表达式 1.2 lambda 表达式的语法 1.3 函数式接口 1.4 方法引用 1.5 构造器引用 1.6 变量作用域 1.7 默认方 ...

  3. Hadoop权限管理

    1.Hadoop权限管理包括以下几个模块: (1) 用户分组管理.用于按组为单位组织管理,某个用户只能向固定分组中提交作业,只能使用固定分组中配置的资源:同时可以限制每个用户提交的作业数,使用的资源量 ...

  4. 深入浅出Git教程(转载)

    目录 一.版本控制概要 1.1.什么是版本控制 1.2.常用术语 1.3.常见的版本控制器 1.4.版本控制分类 1.4.1.本地版本控制 1.4.2.集中版本控制 1.4.3.分布式版本控制 1.5 ...

  5. web service 的跨语言特性

    1.用java语言创建一个的服务(Myservice) ①编写一个Imyservice接口(注解不能少) @WebService public interface Imyservice { publi ...

  6. python 编译源文件

    背景 近期项目到了部署的阶段.由于项目后台和算法都是用Python "撸的",但是又不希望将源代码直接 "release" 到 “客户”哪里.于是开始思考... ...

  7. Java后端框架之Spring Boot详解,文末有Java分布式实战项目视频可取

    在 Java 后端框架繁荣的今天,Spring 框架无疑是最最火热,也是必不可少的开源框架,更是稳坐 Java 后端框架的龙头老大. 用过 Spring 框架的都知道 Spring 能流行是因为它的两 ...

  8. jdk源码阅读笔记-LinkedList

    一.LinkedList概述 LinkedList的底层数据结构为双向链表结构,与ArrayList相同的是LinkedList也可以存储相同或null的元素.相对于ArrayList来说,Linke ...

  9. ssm日期格式转换

    ssm日期格式转换 1      需求 前端传入字符串类型日期转化成java中的Date类型,存入数据库中;将数据库中的日期类型通过jstl标签在前端页面转换成字符串类型. 2      步骤 2.1 ...

  10. 在.NET Core中使用Exceptionless分布式日志收集框架

    一.Exceptionless简介 Exceptionless 是一个开源的实时的日志收集框架,它可以应用在基于 ASP.NET,ASP.NET Core,Web Api,Web Forms,WPF, ...