C语言-5.循环控制

91 阅读7分钟

@TOC

5.1第三种循环

5.1.1for循环:这是最古老的循环,确实样子看上去有点古怪

阶乘 n!=123*4...*n 写出一个程序,让用户输入n,然后计算输出n! 变量: 显然读用户的输入需要一个int的n,然后计算的结果需要用一个变量保存,可以是int的factor,在计算中需要有一个变量不断的从1增加到n,那可以是int的i 代码:

#include<stdio.h>
int main()
{
    int number;
    int i=1;
    int sun=1;
    scanf("%d",&number);
    while(i <= number)
    {
        sun=sun*i;
        i++;
    }
    printf("%d",sun);
}

在c语言中有一种语句叫for语句,可以直接使变量自加。 代码:

#include<stdio.h>
int main()
{
    int number;
    scanf("%d",&number);
    int sum=1;
    for(int i=1;i<=number;i++)
    {
        sum=sum*i;   
    }
    printf("%d",sum);

}

for循环 for循环像一个计数循环:设定一个计数器,初始化它,然后在计数器到达某值之前,重复执行循环体,而每执行一轮循环,计数器值以一定步数进行调整,比如加1或减1。 for(i=0;i<5;i++) { printf("%d",i); } for=对于 for(count=10;count>0;count--) 就读成:“对于一开始的count=10,当count>10时,重复做循环体,每一轮循环在做完循环体内语句后,使得count--” 小套路 做求和的程序时,记录结果的变量应该初始化为0,而做求积的变量时,记录结果的变量应该初始换为1 循环控制变量i只在循环里被使用了,在循环外面它没有任何用处。因此,我们可以把变量i的定义写到for语句里面去 int n; scanf("%d",&n); int fact=1; for(int i=1;i<n;i++) { fact*=i; } for == while for(int i=1;i<=n;i++) { fact*=i; } 等价于: int i=1; while(i<=n) { fact*=i; i++ } for循环 for循环每一个表达式都是可以省略的 for(;条件;) == while(条件) 循环次数 for(i=0;i<n;i++) 则循环的次数是n,而循环结束以后,i的值是n。循环的控制变量i,是选择从0开始还是从1开始,是判断i<n还是判断i<=n,对循环的次数,循环结束后变量的值都有影响 Tips for loops 如果有固定次数,用for 如果必须执行一次,用do_while 其他情况用while

5.2循环控制

5.2.1循环控制:如何用break和continue来控制循环

素数 只能被1和自己整除的数,不包括1 2,3,5,7,11,13,17... 代码:

#include<stdio.h>
int main()
{
    int x;
    scanf("%d",&x);
    int isPream=1;
    for(int i=2;i<x;i++)
    {
        if(x%i==0)
        {
            isPream=0;
            break;
        }
    }
    if(isPream==1)
    {
        printf("是素数");
    }
    else
    {
        printf("不是素数");
    }
}

break vs continue break:跳出循环 continue:跳过循环这一轮剩下的语句进入下一轮 在这里插入图片描述

5.2.2循环的切套:在循环里面还是循环

100以内的素数 如何写程序输出100以内的素数? 代码:

#include<stdio.h>
int main()
{
    
    for(int x=2;x<=100;x++)
    {
        int isPream=1;
        for(int i=2;i<x;i++)
        {
            if(x%i==0)
            {
                isPream=0;
            }
        }
        if(isPream==1)
        {
            printf("%d ",x);
        }
}
}

循环的嵌套 循环里面还是循环 前五十个素数 如何写程序输出前50个素数 代码:

#include<stdio.h>
int main()
{
    int count=0;
    for(int x=2;count<50;x++)
    {
        int isPream=1;
        for(int i=2;i<x;i++)
        {
            if(x%i==0)
            {
                isPream=0;
            }
        }
        if(isPream==1)
        {
            count++;
            printf("%d\t",x);
            if(count%5==0)
            {
                printf("\n");
            }
        } 
    }
    
    return 0;

}

5.2.3从嵌套的循环中跳出:break只能跳出其所在的循环

嵌套循环时的break 凑硬币 如何用1角2角和 5角的硬币凑出10元以下的金额呢? 代码

#include <stdio.h>
int main()
{
    int x;
    scanf("%d", &x);
    int one, two, five;
    for(one = 0; one <= x*10; one++)
    {
        for(two = 0; two <= x*10/2; two++)
        {
            for(five = 0; five <= x*10/5; five++)
            {
                if(one + two*2 + five*5 == x*10)
                {
                    printf("%d元需要%d个一角%d个二角%d个五角\n",x, one, two, five);
                }
            }
        }
    }
    return 0;
}

如果我们想找到一个结果就输出我们可以使用break,但是因为break只能跳出一个for循环所以要用多个break跳出循环。

#include <stdio.h>
int main()
{
    int x;
    int sum = 0;
    scanf("%d", &x);
    int one, two, five;
    for(one = 0; one <= x*10; one++)
    {
        for(two = 0; two <= x*10/2; two++)
        {
            for(five = 0; five <= x*10/5; five++)
            {
                if(one + two*2 + five*5 == x*10)
                {
                    printf("%d元需要%d个一角%d个二角%d个五角\n",x, one, two, five);
                    sum=1;
                    break;
                }
            }
            if(sum==1)
            {
                break;
            }
        }
        if(sum==1)
        {
            break;
        }
    }
    return 0;
}

goto 还有一种语句叫goto语句: 代码:

#include <stdio.h>
int main()
{
    int x;
    scanf("%d", &x);
    int one, two, five;
    for(one = 0; one <= x*10; one++)
    {
        for(two = 0; two <= x*10/2; two++)
        {
            for(five = 0; five <= x*10/5; five++)
            {
                if(one + two*2 + five*5 == x*10)
                {
                    printf("%d元需要%d个一角%d个二角%d个五角\n",x, one, two, five);
                    goto end;
                }
            }
        }
    }
end:
    return 0;
}

在要跳出的地方放一个goto 在goto后面放一个标号,在想要跳出的地方再放一个标号,成立后就会跳到标号的位置。但是尽量少用goto语句: 代码可读性降低 破坏程序的线性结构 传统的程序代码通常按照从上到下的顺序依次执行,这种线性结构符合人类的思维习惯,便于理解。而 goto 语句可以让程序跳转到任意指定的标签处继续执行,这就打破了这种线性的执行顺序。例如在一个包含多个 goto 跳转的程序中,阅读代码时很难按照正常的逻辑顺序去理解程序的执行流程,需要不断在代码中来回查找跳转的目标位置。 增加理解代码逻辑的难度 当代码中存在多个 goto 语句,且跳转关系复杂时,代码的逻辑会变得错综复杂。特别是在大型项目中,不同模块之间可能存在相互跳转,这使得理解代码的整体逻辑变得非常困难,甚至可能导致对代码功能的误解。 代码可维护性变差 修改代码时容易出错 如果需要对使用了 goto 语句的代码进行修改,例如添加或删除一些代码逻辑,很容易因为 goto 语句的跳转关系而影响到其他部分的代码。一个小小的修改可能会导致 goto 语句跳转到错误的位置,从而引发难以调试的错误。 不利于代码的扩展 随着项目的发展,可能需要对代码进行扩展,添加新的功能或逻辑。使用 goto 语句的代码由于其跳转关系的复杂性,很难在不破坏原有逻辑的前提下进行扩展。新添加的代码可能会干扰原有的 goto 跳转,导致代码的稳定性下降。 违反结构化编程原则 结构化编程的优势 结构化编程强调使用顺序、选择和循环三种基本结构来构建程序,这三种结构具有清晰的逻辑和明确的入口与出口,使得程序的结构更加清晰、易于理解和维护。而 goto 语句可以随意跳转,破坏了这种结构化的编程方式。 影响代码的模块化和抽象 良好的代码应该具有模块化和抽象的特点,每个模块负责完成特定的功能,模块之间通过清晰的接口进行交互。goto 语句的使用可能会使代码的模块化和抽象性变差,因为它可以跨越模块的边界进行跳转,使得模块之间的独立性降低,增加了代码的耦合度。 调试困难 难以跟踪程序执行流程 在调试使用了 goto 语句的代码时,由于程序的执行路径不固定,很难通过单步调试等方式准确跟踪程序的执行过程。调试器在遇到 goto 语句时会直接跳转到目标位置,这使得调试人员难以把握程序在不同时刻的状态。 增加定位错误的难度 当程序出现错误时,由于 goto 语句的跳转关系复杂,很难确定错误发生的具体位置和原因。错误可能是由于 goto 语句跳转到了错误的代码段,或者在跳转过程中导致了某些变量的状态异常,但很难通过常规的调试方法快速定位这些问题。