欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

第5章 简单的C程序设计——循环结构程序设计

程序员文章站 2022-03-20 19:11:09
5.1 为什么需要循环控制 前面介绍了程序中常用到的顺序结构和选择结构,但是只有这两种结构是不够的,还需要用到循环结构(或称重复结构)。因为在程序所处理的问题中常常遇到需要重复处理的问题。 循环结构和顺序结构、选择结构是结构化程序设计的3中基本结构。 5.2 用while语句实现循环 while语句 ......

5.1 为什么需要循环控制

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

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

 

5.2 用while语句实现循环

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

while语句的一般形式如下:

while(表达式)语句

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

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

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

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

编写程序:

 1 #include <stdio.h>
 2 int main()
 3 {
 4          int i = 1, sum = 0;
 5          while(i<=100)
 6         {
 7              sum += i;
 8              i++;
 9         }
10     printf(“sum=%d\n”,sum);
11     return 0;
12 }    
1 运行结果:sum=5050

 

循环分析:

(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循环

 1 #include <stdio.h>
 2 int main()
 3 {
 4          int i , sum = 0;
 5          printf(“please enter i=\n”);
 6          scanf("%d",&i);
 7          printf(“%d\n”,i);
 8          while(i<=100)
 9          {
10                   sum += i;
11                   i++;
12          }
13          printf(“sum=%d\n”,sum);
14          return 0;
15 }

 

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

sum = 100

(2)用do……while循环

 1 #include <stdio.h>
 2 int main()
 3 {
 4          int i , sum = 0;
 5          printf(“please enter i=”);
 6          scanf("%d",&i);
 7          printf(“%d\n”,i);
 8          do
 9          {
10                   sum += i;
11                   i++;
12          }while(i<=100)
13          printf(“sum=%d\n”,sum);
14          return 0;
15 }

 

运行的结果为: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时循环结束

 1 //break语句的使用
 2 #include <stdio.h>
 3 int main()
 4 {
 5     int sum = 0;
 6     int i = 0;
 7     for(;i<=100;i++)
 8     {
 9         if(sum>=1000)        //如果sum>1000提前结束循环
10             break;
11         sum += i;
12     }
13     printf("循环的次数为:%d,sum的值为:%d\n",i,sum);
14     return 0;
15 }

break语句的一般形式:

break

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

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

 

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

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

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

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int i=1;
 5     int j=0;     //用®?于®¨²换?行d
 6     for(;i<=100;i++)
 7     {
 8          if(i%3==0&&i%5==0)
 9          {
10              j++;
11              printf("%d\t",i);
12              if(j%5==0)
13                   printf("\n");
14          }
15     }
16     printf("\n");
17     return 0;
18 }

 

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的区别

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int i,j,n=0;
 5     for(i=1;i<=4;i++)
 6     {
 7          for(j=1;j<=5;j++,n++)
 8          {
 9              if(n%5==0)
10                   printf("\n");
11              if(i==3&&j==1)break;
12              printf("%d\t",i*j);
13          }
14     }
15     printf("\n");
16     printf("\n");
17     printf("\n");
18          for(i=1;i<=4;i++)
19     {
20          for(j=1;j<=5;j++,n++)
21          {
22              if(n%5==0)
23                   printf("\n");
24              if(i==3&&j==1)continue;
25              printf("%d\t",i*j);
26          }
27     }
28     return 0;
29 }

 

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对兔子,假如兔子都不死 ,问每个月的兔子总数为多少?

第5章 简单的C程序设计——循环结构程序设计

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

编写程序:

 1 //求fibonacci数列前40项
 2 #include <stdio.h>
 3 int main(){
 4          long int f1,f2;
 5          int i;
 6          f1 = 1;      f2 = 1; //赋初始值
 7          for(i = 1;i<=20;i++){//循环20次,一次两个,结果为前40项
 8                   printf("%12d%12d",f1,f2);//输出 两项
 9                   f1=f1+f2;f2=f2+f1;//计算下面两项
10                   if(i % 2 == 0)  //一行四个 好看用
11                           printf("\n");
12          }
13         return 0;
14 }    

 

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