《小菜狗 C 语言入门 + 进阶笔记》(21)嵌套循环和循环练习

《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介

1、引入

我们前面的章节 (2.19)while 循环(2.20)for 循环 学习了三种循环 while,do while,for,而且三种循环往往会嵌套在⼀起才能更好的解决问题。

循环嵌套就是在一个循环内使用另一个循环。例如 for 里面还有 for,while 里面还有 while,或者 for 里面有 while,while 里面有 if-else,这都是允许的。

在 C 语言中,if-else、while、do-while、for 都可以相互嵌套。 if-else 的嵌套在 (2.17)复杂判断语句和运算符 一节中已经进行了讲解,本节主要介绍循环结构的嵌套。

2、嵌套循环语法

2.1、嵌套 for 循环语句语法
for (initialization; condition; increment/decrement)
{
    statement(s);
    for (initialization; condition; increment/decrement)
    {
        statement(s);
        ... ... ...
    }
    ... ... ...
}

流程图:
在这里插入图片描述

2.2、嵌套 while 循环语句语法
while (condition1)
{
    statement(s);
    while (condition2)
    {
        statement(s);
        ... ... ...
    }
    ... ... ...
}

流程图:
在这里插入图片描述

2.3、嵌套 do…while 循环语句语法
do
{
    statement(s);
    do
    {
        statement(s);
        ... ... ...
    } while (condition2);
    ... ... ...
} while (condition1);

流程图:
在这里插入图片描述

关于嵌套循环有一点值得注意,您可以在任何类型的循环内嵌套其他任何类型的循环。比如,一个 for 循环可以嵌套在一个 while 循环内,反之亦然。

3、for 嵌套实例

3.1、练习1(简单)
输出一个 4×4 的整数矩阵。
#include <stdio.h>
int main()
{
    int i, j;
    for(i=1; i<=4; i++) {      //外层for循环
        for(j=1; j<=4; j++) {  //内层for循环
            printf("%-4d", i*j);
        }
        printf("\n");
    }
    return 0;
}

运行结果:

1   2   3   4
2   4   6   8
3   6   9   12
4   8   12  16

详细解释:

  • 外层 for 第一次循环时i 为 1,内层 for 要输出四次 1*j 的值,也就是第一行数据;内层 for 循环结束后执行 printf(“\n”),输出换行符;接着执行外层 for 的 i++ 语句。此时外层 for 的第一次循环才算结束。
  • 外层 for 第二次循环时i 为 2,内层 for 要输出四次 2*j 的值,也就是第二行的数据;接下来执行 printf(“\n”) 和 i++,外层 for 的第二次循环才算结束。
  • 外层 for 第三次、第四次循环以此类推。

可以看到,内层 for 每循环一次输出一个数据,而外层 for 每循环一次输出一行数据。

详细总结:

本例是一个简单的 for 循环嵌套,外层循环和内层循环交叉执行,外层 for 每执行一次,内层 for 就要执行四次。

在 C 语言中,代码是顺序、同步执行的,当前代码必须执行完毕后才能执行后面的代码。这就意味着,外层 for 每次循环时,都必须等待内层 for 循环完毕(也就是循环 4 次)才能进行下次循环。虽然 i 是变量,但是对于内层 for 来说,每次循环时它的值都是固定的。

3.2、练习2(加深)
输出九九乘法表。
#include <stdio.h>
int main(){
    int i, j;
    for(i=1; i<=9; i++) {      //外层for循环
        for(j=1; j<=i; j++) {  //内层for循环
            printf("%d*%d=%-2d  ", i, j, i*j);
        }
        printf("\n");
    }

    return 0;
}

运行结果:

1*1=1
2*1=2   2*2=4
3*1=3   3*2=6   3*3=9
4*1=4   4*2=8   4*3=12  4*4=16
5*1=5   5*2=10  5*3=15  5*4=20  5*5=25
6*1=6   6*2=12  6*3=18  6*4=24  6*5=30  6*6=36
7*1=7   7*2=14  7*3=21  7*4=28  7*5=35  7*6=42  7*7=49
8*1=8   8*2=16  8*3=24  8*4=32  8*5=40  8*6=48  8*7=56  8*8=64
9*1=9   9*2=18  9*3=27  9*4=36  9*5=45  9*6=54  9*7=63  9*8=72  9*9=81

和练习1(简单)一样,内层 for 每循环一次输出一条数据,外层 for 每循环一次输出一行数据。 需要注意的是:

内层 for 的结束条件是j<=i。外层 for 每循环一次,i 的值就会变化,所以每次开始内层 for 循环时,结束条件是不一样的。

具体如下:

  • 当 i=1 时,内层 for 的结束条件为 j<=1,只能循环一次,输出第一行。
  • 当 i=2 时,内层 for 的结束条件是 j<=2,循环两次,输出第二行。
  • 当 i=3 时,内层 for 的结束条件是 j<=3,循环三次,输出第三行。
  • 当 i=4、5、6… 时,以此类推。
3.3、练习3(进阶)
查找 2 到 100 中的质数。
#include <stdio.h>
 
int main ()
{
   /* 局部变量定义 */
   int i, j;
   
   for(i=2; i<100; i++) {
      for(j=2; j <= (i/j); j++)
          if(!(i%j)) 
              break; // 如果找到,则不是质数
      if(j > (i/j))
          printf("%d 是质数\n", i);
   }
 
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

2 是质数
3 是质数
5 是质数
7 是质数
11 是质数
13 是质数
17 是质数
19 是质数
23 是质数
29 是质数
31 是质数
37 是质数
41 是质数
43 是质数
47 是质数
53 是质数
59 是质数
61 是质数
67 是质数
71 是质数
73 是质数
79 是质数
83 是质数
89 是质数
97 是质数

4、while 嵌套实例

4.1、练习1(简单)
输出一个 5×5 的整数倒三角形阵。
#include <stdio.h>
int main()
{
    int i=1,j;
    while (i <= 5)
    {
        j=1;
        while (j <= i )
        {
            printf("%d ",j);
            j++;
        }
        printf("\n");
        i++;
    }
    return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5

5、do while 嵌套实例

5.1、练习1(简单)
输出一个 5×5 的 * 号倒三角形阵。
#include <stdio.h>
int main()
{
    int i=1,j;
    do
    {
        j=1;
        do
        {
            printf("*");
            j++;
        } while(j <= i);
        i++;
        printf("\n");
    } while(i <= 5);

    return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

*
**
***
****
*****

6、循环实例扩展

6.1、求 1~100 以内所有的奇数和、偶数和
6.1.1、使用 while
#include  <stdio.h>

int main(){
    int  sum=0;
    int  num=1;
    int  sum2=0;
    int  num2=2;
    while(num<100) {
        sum=sum+num;
        num=num+2;
    }
    printf("奇数和为:%d\n",sum);

    while(num2<=100) {
        sum2=sum2+num2;
        num2=num2+2;
    }
    printf("偶数和为:%d\n",sum2);
}
6.1.2、使用 for
#include  <stdio.h>

int main(){

    int sum=0;
    int sum2=0;
    int num,num2;
    for(num=1; num<100; num=num+2){
        sum=sum+num;
    }
    printf("奇数和%d\n",sum);
    for(num2=2; num2<=100; num2=num2+2){
        sum2=sum2+num2;
    }
    printf("偶数和%d\n",sum2);
}
6.1.3、改良代码
#include<stdio.h>

int main()
{
    int num=0, odd=0, even=0;
    for(; num<=100; num++)
    {
        if(num%2==0)
            even+=num;
        else
            odd+=num;
    }

    printf("Odd number sum is %d\n",odd);
    printf("Even number sum is %d\n",even);
    return 0;
}
6.2、求算术平方根

6.2.1、使用 do while

#include <stdio.h>

double DoSqrt(double z){
    double a=1;
    double b=0;
    double c=0;
    do {
        if(b*b<z) {
            b+=a;
        }
        else {
            c=b;
            b-=a;
            a/=10;
        }
    } while(a>0.000001);

    return (b+c)/2;
}

int main(){
    double x, y;
    printf("请输入一个数字:");
    scanf("%lf", &x);
    if(x<0) {
        printf("输入错误。");
    } else {
        y=DoSqrt(x);
        printf("%g 的平方根为: %g.\n", x, y);
    }

    int z=1;
    do {
        main();
        z++;
    } while(z>10);

    return 0;
}
6.3、求 100 以内的素数
#include<stdio.h>
#include<math.h>

int main(){
    int i,j;
    printf("100以内的素数有:\n");
    for (i=2; i<100; i++) {
        for (j=2; j<sqrt(i); j++) {
            if (i%j==0) {
                break;
            }
        }
        if (j>sqrt(i)) {
            printf("%d,\t",i);
        }
    }
}
  • 第一个循环里面,i 遍历从 2 到 100 以内的所有数字;
  • 第二个循环是在 2 到 sqrt(n)之间看看是不是可以整除 i;
  • 可以整除则不是素数,相反不可以整除,则是素数。
int fun(int n) {
    for (i=2; i<=sqrt(p); i++) {  
        if (x%i==0) {
            return 0;  //不为素数
        } else {
            return 1; //为素数 
        }
    }
}

这个是求素数子函数的关键代码。希望初学者要理解。

《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介


每日一更!

公众号、优快云等博客:小菜狗编程笔记

谢谢点赞关注哈!目前在飞书持续优化更新~

日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小菜狗编程笔记

你的鼓励将是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值