云边日落 花落水流红,闲愁万种,无语怨东风。(元·王实甫·西厢记)
博主 云边日落
渝ICP备2021002886号-1渝公网安备50022502000591号博主 11月5日 在线自豪地使用 Typecho 建站搭配使用 🌻Sunny 主题当前在线 3 人
歌曲封面 未知作品
  • 歌曲封面“魔女の宅急便”~ルージュの伝言松任谷由実

渝ICP备2021002886号-1

渝公网安备50022502000591号

网站已运行 4 年 152 天 16 小时 19 分

Powered by Typecho & Sunny

3 online · 41 ms

Title

循环结构

郭儿宝贝

·

·

151次阅读
编辑语言
Article
⚠️ 本文最后更新于2021年08月17日,已经过了1191天没有更新,若内容或图片失效,请留言反馈

在程序设计中,如果需要重复执行某些操作,就要用到循环结构。所以在使用循环结构编程时,

要明确:

哪些操作需要反复执行?这些操作在什么情况下重复执行?
循环体循环条件

明确后就可以选用C语言中的for,while和do-while来实现循环。

首先来看看while语句。

while语句

除了for语句,while语句也用于实现循环,且它的适用面更广,一般形式为:

♾️ c 代码:
    while ( 表达式)
      循环体语句;    //一条语句

首先判断表达式的真假,如果值为真,循环执行,直到表达式的值为假,循环终止并继续执行while的下一条语句。

for,while都是在循环前先判断条件

把 for 语句改写成 while 语句

♾️ c 代码:
  for (表达式1; 表达式2; 表达式3)
      循环体语句

修改为while语句:

♾️ c 代码:
表达式1;
while (表达式2) {
    for的循环体语句;
    表达式3;
}

注意:修改的前提是for的循环体语句中没有使用continue语句。
for循环和while循环的区别:
for是计数循环;
while是无法计数时使用。

实例1:求平均成绩

从键盘输入一批学生的成绩,计算平均成绩,并统计不及格学生的人数。
代码如下:

♾️ c 代码:
# include <stdio.h>
int main (void)
{   
    int count, num; double score, total; 
    num = 0; total = 0; count=0;
    printf ("Enter scores: \n"); 
    scanf ("%lf", &score);     /* 输入第1个数*/
    while (score >= 0) {         /* 输入负数,循环结束 */
        total  = total + score;   //累加成绩
        num++; 
        if (score < 60) {
             count++; 
         }
        scanf ("%lf", &score);  //读入一个新数据,为下次循环做准备
    }
    if (num != 0) {
          printf("Average is %.2f\n", total/num);
          printf("Number of failures is %d\n", count); 
    } else {
          printf("Average is 0\n");
    }
    return 0;
}

运行结果:

♾️ c 代码:
Enter scores: 67 88 73 54 82 -1
Average is 72.80
Number of failures is 1

实例2:统计一个整数的位数

从键盘读入一个整数,统计该数的位数。
以12345为例:
12345/10=1234;
1234/10=123;
123/10=12;
12/10=1;
1/10=0.
计算了5次,当输出为0时输出结果,所以12345是一个五位数。
由于需要处理的数据有待输入,故无法事先确定循环次数。故引用do-while循环。

代码如下:

♾️ c 代码:
int main (void)
{  
  int count, number, t_number;
  printf ("Enter a number: ");
  scanf ("%d", &number) ;
  t_number = number;//保护输入数据
  if (t_number < 0){
     t_number = - t_number;
  } 
  count = 0;
  do {
      t_number = t_number / 10;         
      count ++;    
  } while (t_number != 0);
  printf ("It contains %d digits.\n", count);
  return 0;
}

运行结果:

♾️ c 代码:
Enter a number: 12534
It contains 5 digits.
do-while语句

特点:先执行循环体,后判断循环条件。无论循环条件的值如何,

至少会执行一次循环体

一般形式为:

♾️ c 代码:
do {
    循环体语句
} while (表达式)

实例3:将一个整数逆序输出

分离方法:
对10求余,从低位开始分离。
设n=12345,从低位开始分离:
12345%10=5;继续求余,但需先将n的值改变为1234:12345/10=1234.
重复上述操作:
1234%10=4
1234/10=123;
123%10=3
123/10=12;
12%10=2
12/10=1;
1%10=1
1/10=0
当n最后等于0时,处理过程结束。

由上述操作可得:

  • 需重复处理的操作:
    n%10,分离一位,
    n/10,为下一次分离做准备;
  • 循环条件:
    n!=0.

代码如下:

♾️ c 代码:
scanf ( "%d", &number );
do{  //输入0,循环也要执行一次
     digit = number %10;  //分离一位,
     number = number / 10; //为下一次分离做准备;
     printf ( "%d  ", digit );
} while ( number != 0 )  //n==0时跳出循环

输出结果:

♾️ c 代码:
12345
5 4 3 2 1

实例4:判断素数

输入一个正整数m,判断它是否为素数。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。

判断一个数m是否为素数,需要检查该数是否能被1和自身以外的其他数整除,即判断m是否能被2到m-1之间的整数整除。用求余运算来判断整除余数为0,表示能被整除,否则就不能被整除。

代码如下:

♾️ c 代码:
int i, limit, m;
scanf ("%d", &m);      
if(m <= 1){ 
  printf ("No!\n");
}else if(m == 2){ 
  printf ("Yes!\n"); 
}else{ 
  limit = sqrt(m) + 1;  /* 考虑浮点数运算误差 */
  for (i = 2; i <= limit; i++){          
    if (m % i == 0){
        break;
    }
  }
}
if (i > limit)
  printf ("Yes!\n"); 
else 
  printf ("No!\n"); 
} 

运行结果:

♾️ c 代码:
2
Yes
break语句和continue语句

我们通过一个表格来区别这两种语句。

breakcontinue
强制循环结束跳过后面语句继续下一次循环
不再执行循环体中位于其后的其他语句跳过循环体中continue后的语句,继续下一次循环
和if语句配合使用,满足条件时才跳出循环
可用于中止循环和switch语句只能用于循环

实例5:猜数游戏

代码如下:

♾️ c 代码:
int  count = 0, flag, mynumber, yournumber;            
mynumber = 38;   /* 计算机指定被猜的数 */
flag = 0;         /* flag: 为0表示没猜中,为1表示猜中了*/
while (count < 7){               /* 最多能猜7次 */
  printf ("Enter your number: ");     
  scanf ("%d", &yournumber);
  count++; 
  if ( yournumber == mynumber ) {      /* 若相等,显示猜中 */
    printf ("Lucky You!\n");
    flag = 1;
    break;                       /* 已猜中,终止循环 */
  }else if ( yournumber > mynumber ) printf("Too big\n");
  else printf("Too small\n");
  }
if ( flag == 0 )                     /* 超过7次还没猜中,提示游戏结束 */
     printf ("Game Over!\n"); 

运行结果:

♾️ c 代码:
38
Lucky You! 

实例6:求阶乘和1! + 2! + … + n!

代码如下:

♾️ c 代码:
# include <stdio.h>
double fact (int n); 
int main (void)
{     
    int i, n;
     double sum;
     printf("Enter n: ");
     scanf("%d", &n);
     sum = 0;
     for ( i = 1; i <= n; i++ ){
         sum = sum + fact (i);
     }
    printf ("sum = %.0f\n", sum);
    return 0;
}
double fact (int n)  // 定义求n!的函数
{    
     int i;
     double result;
 
     if(n < 0) return 0;
     result = 1;
     for ( i = 1; i <= n; i++){
           result = result * i ;
      }
      return  result ; 
}

运行结果:

♾️ c 代码:
Enter n: 15
Sum = 1401602636313
嵌套循环
♾️ c 代码:
sum = 0;
for ( i = 1; i <= n; i++ ) {   
  item = 1;                         /*  每次求阶乘都从1开始 */           
  for (j = 1; j <= i; j++){     /* 内层循环算出 item = i! */
    item = item * j;
  }
  sum = sum + item;  
}

上述循环即为嵌套循环,在for循环中嵌入一个for循环。

  • 外层循环变量 i 的每个值,内层循环变量 j 变化一个轮次;
  • 内外层循环变量的名字不能相同,分别用 i 和 j。
循环结构程序设计

注意区分循环结构和分支结构。

  • 循环结构的实现要点:
    归纳出哪些操作需要反复执行?——循环体
    这些操作在什么情况下重复执行? ——循环条件

    循环次数=外循环次数*内循环次数

实例7:求最值

输入一批学生的成绩,求最高分。
先输入一个成绩,假设它为最高分,然后在循环中读入下一个成绩,并与最高分比较,如果大于最高分,就设它为新的最高分,继续循环,直到所有的成绩都处理完毕。
一般有以下两种途径:

  • for语句:
    代码如下:

    ♾️ c 代码:
    #include <stdio.h>
    int main(void)
    {  
     int i, mark, max, n;  
     printf("Enter n: ");    scanf ("%d", &n); 
     printf("Enter %d marks: ", n);
     scanf ("%d", &mark);                /* 读入第一个成绩 */
     max = mark;                  /* 假设第一个成绩是最高分 */
     for (i = 1; i < n; i++ ){     
          scanf ("%d", &mark);   
          if (max < mark){
              max = mark;
          }     
     } 
     printf("Max = %d\n", max);
     return 0;
    }
  • while语句
    代码如下:

    ♾️ c 代码:
    #include <stdio.h>
    int main(void)
    {     
         int mark, max; 
         printf(“Enter marks:"); 
         scanf ("%d", &mark);   /* 读入第一个成绩 */
         max = mark;          /* 假设第一个成绩最高分 */
         while (mark >= 0){
              if(max < mark){ 
                    max = mark ; 
               }
               scanf ("%d", &mark );
         };
         printf("Max = %d\n", max);
         return 0;
    }
    

实例8:斐波那契(Fibonacci)数列问题

输出斐波那契(Fibonacci)数列的前n项(1<=n<=46) ,每行输出5个。
任一项数字是前两项的和,最开始两项均为1。
1, 1, 2, 3, 5, 8, 13, ……即任意项数字是前两项的和的数列。

代码如下:

♾️ c 代码:
  int i,n,x1,x2,x;
  
  printf("Enter n: ");     
  scanf ("%d", &n);
  if(n < 1 || n > 46){
    printf("Invalid.\n");
  }else if (n == 1){ 
    printf ("%10d", 1);         /* 输出第1项 */
  }else{
    x1 = 1;
    x2 = 1;                                  /* 头两项都是1 */
    printf ("%10d%10d", x1, x2);     /* 先输出头两项 */
    for (i = 3; i <= n; i++) {         /* 循环输出后n-2项 */
        x = x1 + x2;                   /* 计算新项 */
        printf("%10d", x); 
        if(i % 5 == 0){  
          printf("\n"); 
        }  
        x1 = x2;   
        x2 = x;    
        }
    }
    return 0;
    

运行结果:

♾️ c 代码:
Enter n: 10
  1    1    2    3    5     
  8    13   21   34   55

本题采用迭代的方法计算斐波那契数列,迭代法也称辗转法,是一个不断从变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。

实例9:素数问题

输入2个正整数m和n(1<=m<=n<=500),输出m到n之间的全部素数,每行输出10个。
素数就是只能被1和自身整除的正整数,1不是素数,2是素数。
采用二重循环嵌套:

♾️ c 代码:
for (k = m; k <= n; k++)
    if (k是素数)  printf( "%d", k);

代码如下:

♾️ c 代码:
  printf("Enter m n: "); 
  scanf ("%d%d", &m, &n);
  if(m < 1 || n > 500 || m > n) 
    printf("Invalid.\n");
  else{
      for(k = m; k <= n; k++){
          if (k <= 1) flag = 0; 
          else if (k == 2) flag = 1;
          else{  
              flag = 1;        /* 先假设k是素数 */
              limit = sqrt(k) + 1;
              for(i = 2; i <= limit; i++){
                 if(k % i == 0){    /* 若k能被某个i整除,则k不是素数 */
                     flag = 0;    /* 置flag为 0 */
                     break;        /* 提前结束循环 */
                 }  
              }
            }
            if (flag == 1){                  /* 如果k是素数 */
               printf("%6d", k);       /* 输出k */
               count++;                 /* 累加已经输出的素数个数 */
               if(count % 10 == 0) printf("\n");  
            }
        }
    }
    return 0;

实例10:搬砖问题(三重嵌套)

某地需要搬运砖块,已知男人一人搬3块,女人一人搬2块,小孩两人搬一块。
问用n人正好搬n块砖,有多少种搬法?
代码如下:

♾️ c 代码:
limit_m = n/3;   limit_w = n/2;
for(men = 0; men <= limit_m; men++){
     for(women = 0; women <= limit_w; women++){
         child = n - men - women; 
         if((men*3 + women*2 + child*0.5 == n)){
            printf("men=%d, women=%d, children=%d\n", men, women, child);
        }
    }
}

实例11:找零钱问题

有足够数量的5分、2分和1分的硬币,现在要用这些硬币来支付一笔小于1元的零钱money,问至少要用多少个硬币?
输入零钱,输出硬币的总数量和相应面额的硬币数量。

硬币总数最小:优先考虑使用面值大的硬币
采用三重循环嵌套
按照5分、2分和1分的顺序,从上限(money/币值)到下限(0)

代码如下:

♾️ c 代码:
flag = 1;      /* flag表示是否中止嵌套循环 */
printf("Enter money: ");    scanf("%d", &money);
for (n5 = money/5; (n5 >= 0) && (flag == 1); n5--){
   for (n2 = (money-n5*5)/2; (n2 >= 0) && (flag == 1); n2--){
      for (n1 = money-n5*5-n2*2; (n1 >=0) && (flag == 1); n1--){
          if ((n5*5 + n2*2 + n1) == money) {
             printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n", n5, n2, n1, n1+n2+n5);
             /* 置flag为 0,则三重循环的条件都不满足,中止嵌套循环 */
             flag = 0;     
          }
        }
      }
  }
      
现在已有 0 条评论,0 人点赞
Author:郭儿宝贝
作者
循环结构
当前文章累计共 9261 字,阅读大概需要 5 分钟。
1个C语言程序
2021年4月10日 · 0评论
循环结构
2021年7月17日 · 0评论
C语言的语法
2021年4月22日 · 0评论
Comment:共0条
发表
搜 索 消 息 足 迹
你还不曾留言过..
你还不曾留下足迹..
博主 不再显示
博主