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


    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
    ”,sum);
    11     return 0;
    12 }    
    View Code
    1 运行结果:sum=5050
    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循环

     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
    ”,i);
     8          while(i<=100)
     9          {
    10                   sum += i;
    11                   i++;
    12          }
    13          printf(“sum=%d
    ”,sum);
    14          return 0;
    15 }
    while

    运行的结果为: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
    ”,i);
     8          do
     9          {
    10                   sum += i;
    11                   i++;
    12          }while(i<=100)
    13          printf(“sum=%d
    ”,sum);
    14          return 0;
    15 }
    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())!=’ ’;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
    ",i,sum);
    14     return 0;
    15 }
    break Code

    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	",i);
    12              if(j%5==0)
    13                   printf("
    ");
    14          }
    15     }
    16     printf("
    ");
    17     return 0;
    18 }
    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的区别

     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("
    ");
    11              if(i==3&&j==1)break;
    12              printf("%d	",i*j);
    13          }
    14     }
    15     printf("
    ");
    16     printf("
    ");
    17     printf("
    ");
    18          for(i=1;i<=4;i++)
    19     {
    20          for(j=1;j<=5;j++,n++)
    21          {
    22              if(n%5==0)
    23                   printf("
    ");
    24              if(i==3&&j==1)continue;
    25              printf("%d	",i*j);
    26          }
    27     }
    28     return 0;
    29 }
    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项,用循环即可。

    编写程序:

     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("
    ");
    12          }
    13         return 0;
    14 }    
    View Code

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

  • 相关阅读:
    清理计算机硬盘
    DIY-组装
    go函数类型的使用
    go同步互斥锁
    Go读写文件
    go mod
    go html
    channel
    arp和rarp协议
    自己实现的反射
  • 原文地址:https://www.cnblogs.com/HOsystem/p/10760380.html
Copyright © 2020-2023  润新知