04(下) ——循环结构

一、循环结构
在生活中我们常常遇到需要重复处理的问题,我们在编程时解决需要重复处理的问题需要使用循环语句
循环语句主要有3种:while()循环;do-while()循环和for()循环
1、while()循环
用法:
while(循环条件)
{
    循环体;
    ……
}
说明:
当程序遇到while()循环的时候,首先会判断while()的括号内的表达式,若为真(即满足循环条件)则执行循环,执行完循环体后再次返回到while();若为假则结束循环
示例:
输入10个学生的成绩,输出这10个学生的成绩总和以及平均分
int main()
{
    int i = 1,count = 0,input = 0;//i用来控制循环次数,count用于总和,input用于每次输入
    float avg = 0;//avg用于平均分
    while(i<=10)//循环条件
    {
        printf("请输入第%d个学生的成绩:\n",i);
        scanf("%d",&input);
        count += input;
        i++;//不要忘了让i++
    }
    avg = (float)count/10;
    printf("总成绩是%d\n平均成绩是%f\n",count,avg);
    return 0;
}
思考:若在循环体中没有i++这一句将会发生什么结果?
答案:i++这一句的作用是改变循环的状态。若没有i++这句,则i的值会永远是1,则循环永远都不会结束,即程序会进入死循环
初学者在使用循环时一定要注意不要陷入死循环。当你的程序使用了循环结构,在编译阶段无语法错误,在执行时发现程序会无限期进行下去,则很可能你的程序进入了死循环。此时要检查循环条件设置是否正确,以及检查是否设置了改变循环状态的量。
若发生了死循环,按ctrl+c(或ctrl+z)组合键可强制终止当前程序
练习:求1+2+3+……+100=?
答案:
int main()
{
    int i=0,sum=0;
    while(i<=100)
    {
        sum += i;
        i++;
    }
    printf("和是%d\n",sum);
    return 0;
}

若while()后没有{}限制,则循环只执行到while()后第一个分号处(即只执行一条语句),这点与if()-else相同

2、do-while()循环
用法:
do
{
    循环体;
    ……
}while(循环条件);
说明:
当程序遇到do,会首先执行do下面的语句(即循环体),之后执行到while(),判断while()的括号内的表达式是真/假,若为真(即满足循环条件)则返回do语句处再次执行循环体;若为假则结束循环。
示例:将上文示例改写成do-while()循环
int main()
{
    int i = 1,count = 0,input = 0;//i用来控制循环次数,count用于总和,input用于每次输入
    float avg = 0;//avg用于平均分
    do//循环开始
    {
        printf("请输入第%d个学生的成绩:\n",i);
        scanf("%d",&input);
        count += input;
        i++;//不要忘了让i++
    }while(i<=10);//循环条件
    avg = (float)count/10;
    printf("总成绩是%d\n平均成绩是%f\n",count,avg);
    return 0;
}
练习:将上文练习“1+2+3+……+100=?”改写成do-while()循环
答案:
int main()
{
    int i=0,sum=0;
    do
    {
        sum += i;
        i++;
    }while(i<=100);
    printf("和是%d\n",sum);
    return 0;
}

while()与do-while()的区别:
while()循环是先判断循环条件,再进入循环体。而do-while()循环是先进入循环体,再判断循环条件。
while()循环有可能不执行循环体,而do-while()循环一定会执行一次循环体

3、for()循环
用法:
for(表达式1;表达式2;表达式3)
{
    循环体;
    ……
}
注意:for()括号内的3个表达式的分隔符是分号;不是逗号,
说明:
表达式1:循环的初始条件,只执行一次。可以为0个、1个或多个变量设置初值
表达式2:判断循环结束的条件。在每次执行循环体前判断此表达式,若表达式为真则进入循环,否则不执行循环
表达式3:作为循环的调整(即改变循环状态),在执行完循环体之后执行
for(表达式1;表达式2;表达式3)
{
    循环体;
}
等价于:
表达式1;
while(表达式2)
{
    循环体;
    表达式3;
}
表达式1可以省略。若如此做,相当于没有给for()循环设定起始初值。因此,若要循环正常进行,需要在for()之前设置好循环起始初值
表达式2可以省略。若如此做,相当于for()循环没有结束条件,即死循环。等价于:
while(1)
{
    循环体;
    表达式3;
}
表达式3可以省略。若如此做,需要在循环体内设置循环调整语句,否则循环无法正常执行。
若将3个表达式都省略(即for(;;)),则相当于设置了一个无限循环
若for()后没有{}限制,则循环只执行到for()后第一个分号处(即只执行一条语句),这点与if()-else相同
示例:将上文示例改写成for()
答案:
int main()
{
    int i,count=0,input=0;
    float avg;
    for(i=0;i<10;i++)
    {
        printf("请输入第%d个学生的成绩:\n",i+1);
        scanf("%d",&input);
        count += input;
    }
    avg = (float)count/10;
    printf("总成绩是%d\n平均成绩是%f\n",count,avg);
    return 0;
}
练习:将上文练习“1+2+……+100”改写成for()循环
答案:
int main()
{
    int i,sum=0;
    for(i=1;i<=100;i++)
        sum += i;
    printf("和是%d\n",sum);
}
三种循环的比较:
1)如果使用while()或do-while(),需要注意在循环体内设置改变循环状态的变量。而for()循环则是在表达式3中设置
2)一般来说,for()循环的表达式3的位置甚至可以将循环体都放入,所以for()循环更常用
3)在知道循环次数的情况下,推荐使用for()循环;在不知循环次数的情况下推荐使用while()或do-while()循环
4)从C99版本开始,C语言支持以下用法:
for(int i=0;i<10;i++)
{
    循环体;
    ……
}
这样就可以不用事先特地定义一个用于循环的变量,随时使用随时定义即可。
注意1:这种使用方式循环变量i的生命周期仅仅是在for()循环中,当for()循环结束i即结束其生命周期。如果这样使用:
for(int i=0;i<10;i++)
{
    循环体;
    ……
}
printf("%d",i);//此时i的生命周期已经结束,企图访问不存在的变量i,非法
则编译会显示语法错误。
注意2:这种用法仅支持C99及以后C语言版本的编译器,如果这样使用出现语法错误则证明其编译器版本不支持这种语法,请不要使用这种语法而是在for()循环开始前就定义循环变量。

练习:打印斐波那契数列的前n项,其中n由键盘输入。斐波那契数列的特点如下:
F1=1            (n=1)
F2=1            (n=2)
Fn=Fn-1 + Fn-2  (n>=3)
答案:
int main()
{
    int f1=1,f2=1,i,n;
    printf("请输入循环次数:");
    scanf("%d",&n);
    for(i=1;i<=n/2;i++)//因为每次打印2个数,所以循环次数是n/2次
    {
        printf("%d\n%d\n",f1,f2);
        f1=f1+f2;
        f2=f2+f1;
    }
    return 0;
}

4、循环的嵌套使用
一个循环体内又包含一个循环体的结构称之为循环的嵌套。内嵌循环还可以再嵌套循环。3种循环都是可以互相嵌套使用的。例如下面的例子都是合法的:
1)
while()
{
    do
    {
        
    }while();
}
2)
for(;;)
{
    while()
    {
        
    }
}
3)
do
{
    for()
    {
        
    }
}while();
使用循环嵌套时,需要注意内层循环与外层循环之间的关系,避免出现死循环。
练习1:输出如下图形:
     *
    ***
   *****
  *******
 *********
***********
其中需要输出几行由键盘输入。
答案:
#include<stdio.h>
int main()
{
    int len,i,j;
    printf("please input line:");
    scanf("%d",&len);
    for(i=0;i<len;i++)
    {
        for(j=0;j<len-i-1;j++)
            printf(" ");
        for(j=0;j<2*i+1;j++)
            printf("*");
        printf("\n");
    }
    return 0;
}
练习2:现有100元钱要买以下3种文具。其中一个笔记本20元,一套尺6元,一个笔4元,每样文具至少买1个。列举出所有的购买方案,以及列举出所有正好花光100元的购买方案
答案:
int main()
{
    int i,j,k,count=0;
    //计算总共多少方案
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=16;j++)
        {
            for(k=1;k<=25;k++)
            {
                if(i*20+j*6+k*4<=100)
                {
                    printf("买%d个笔记本,%d套尺,%d个笔,共%d元\n",i,j,k,i*20+j*6+k*4);
                    count++;
                }
            }
        }
    }
    printf("共%d种\n",count);
    count=0;
    //计算花光100元总共多少种方案
    printf("花光100元的方案有:\n");
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=16;j++)
        {
            for(k=1;k<=25;k++)
            {
                if(i*20+j*6+k*4==100)
                {
                    printf("买%d个笔记本,%d套尺,%d个笔\n",i,j,k);
                    count++;
                }
            }
        }
    }
    printf("花光100元共%d种\n",count);
    return 0;
}
5、提前结束循环的语句:continue、break、return、exit()
1)continue
continue语句的用法是:
continue;
其作用是结束本次循环,即跳过所有continue下的语句,进入下次循环。
示例:输出100~200之间不能被3整除的整数
int main()
{
    int n;
    for(n=100;n<=200;n++)
    {
        if(n%3==0)
            continue;//结束本次循环,进入下次循环
        printf("%d ",n);
    }
    printf("\n");
    return 0;
}
2)break
break语句的用法是:
break;
其作用是结束循环,执行循环体外的下一个语句
回顾:break在switch()语句中的作用
break在switch()语句中的作用是跳出switch()语句,执行switch()语句下一条语句。
示例:从r=1开始,输出所有半径是正整数的圆的面积,直至出现面积大于100为止
#include<stdio.h>
#define PI 3.141592
int main()
{
    int r=1;
    float area;
    while(1)//死循环
    {
        area = r*r*PI;
        printf("半径%d的圆面积是%f\n",r,area);
        r++;
        if(area>=100)
            break;
    }
    return 0;
}
可以看到,尽管在示例程序中while()循环使用了死循环,当出现break语句后,依然会跳出循环。
3)return
return语句的用法是:
return 需要的返回值;
其中需要的返回值由函数类型决定。如main()函数是int类型,则需要返回一个整数。如果函数是void类型则无需写返回值。
return语句的作用是结束当前函数,并将返回值返回给函数调用的位置。
有关return语句的用法我们将在函数的课程中详细讲解。
需要注意的是return不仅仅是结束了循环,更是结束了当前的函数。因此要慎用。
4)exit
exit语句的用法是:
exit(x);//x为0或正整数
当x为0时表示正常结束,不为0时表示异常结束(异常号)
exit()在头文件 stdlib.h 中
exit()不仅仅是结束循环,它的真正意义是退出当前程序。因此非常不推荐使用exit()结束循环
从效果来看,4个语句的效果如下:
exit() > return > break > continue
强<---------------------------->弱

练习:输出100~200间的所有素数
答案:
int main()
{
    int i,j;
    for(i=100;i<=200;i++)//外层循环,表示当前数字
    {
        for(j=2;j<=i/2;j++)//内层循环,表示除数
        {
            if(i%j==0)
            {
                break;
            }
        }
        if(j>i/2)
        {
            printf("%d是质数\n",i);
        }
    }
    return 0;
}
/***************goto语句**************/
6、goto语句
用法:
goto 语句标号;
说明:
goto语句是无条件跳转语句,当执行到goto语句时,程序会跳转到goto语句所指向的标号处。语句标号的命名规则与C语言标识符的命名规则相同。
示例:
int main()
{
    label_1:
    ……
    ……
    goto label_1;
}
滥用goto语句会使程序无规律、可读性差。goto语句违背了C语言的模块化编程的基本思想,因此goto语句不推荐使用。
/***************goto语句end***********/

猜你喜欢

转载自blog.csdn.net/qq_34427165/article/details/81209951