程序的循环与控制

        人生就是日复一日地不断重复,既有相同的事情,也有相似的事情,却无论如何也无法回到最初。想要在生活的每一刻都能有新的发现,恐怕只是一个美好的愿望。        

        本章将会为大家介绍程序设计中的重复流程——循环。

        C语言中提供了3种循环执行程序语句:do语句,while循环,for循环。首先我们来看一下do语句。

do语句

        首先我们对上两节介绍的代码中(显示输入的整数是奇数还是偶数)进行一下修改。

        输入一个整数,显示出它是奇数还是偶数。然后询问是否重复同样的操作,并按照要求进行处理。

\\输入的整数是奇数还是偶数呢?
#include <stdio.h>
int main()
{
    int retry;
    do{
        int num;
        printf("请输入一个整数:");
        scanf("%d",&num);
        if(num%2)
            puts("这个整数是奇数。");
        else
            puts("这个整数是偶数。");
        printf("要重复一次吗?[yes~~~0/no~~~9]:");
        scanf("%d",&num);
}while(retry==0);
    return 0;
}

          do是“执行”的意思,while是“在······期间”的意思。根据do语句的处理流程,只要()中的表达式的判断结果不是0,语句就会循环执行。

        另外,do语句循环的对象语句称为循环体

        ▶下面也要讲的while语句和for语句所循环的语句也称为循环体。

        在上述代码中,如果读取到的变量retry的值为0,那么控制编排大师retry==0的判断结果就为1。因为1不等于0,所以身为复合语句的循环体会再次执行。也就是说,判断结果不为0的话,程序会返回到复合语句的开头,然后重新执行复合语句。

        如果读取到的变量retry的值不为0,那么控制表达式retry==0的判断结果就为0,do语句就结束了。

        下面我们用我们所学的switch与do···while来写一个石头剪刀布的程序。

\\根据读取的整数值显示所出的拳(只接受0,1,2)
#include <stdio.h>
int main()
{
    int hand;
    do{    
        printf("请选择出什么拳【0···拳头/1···剪刀/2···布】:");
        scanf("%d",&hand);
       }while(hand<0||hand>2)
        printf("你选择了:");
    switch(hand)
        {
            case 0:printf("石头。");    break;
            case 1:printf("剪刀。");    break; 
            case 2:printf("布。 ");     break; 
        }
    return 0;
}

        首先我们来试一下。如果读取的数值是0,1,2这些“合法的值”,就会显示“石头”“剪刀”“布”。而如果输入3或者-3这样“非法的值”,就会提醒你再次输入。

        我们在来看一下判断do语句的循环是否继续的控制表达式。

        hand<0||hand>2

        我们前面讲过,这是逻辑或语句,只要满足一条则就为真。如果hand的值是0,1,2中的一个,则do语句执行结束。换句话说,do语句执行结束的时候,hand的值一定是0,1,2中的一个。

当然我们也可以把条件写成下面这种形式。

        !(hand>=0&&hand<=2)

        这里的!被称为逻辑非运算符是判断操作数是否等于0的单目运算符。

        逻辑非运算符        !a        当a的值是0的时候值为1,当a的值不是0的时候值为0.

        我们再用所学知识来求多个整数的和及平均值。

\\不停地输入整数,显示其和及平均值
#include <stdio.h>
int main()
{
    int sum=0;
    int count=0;
    int retry;
    do{
        int t;
        printf("请输入一个整数:");
        scanf("%d",&t);
        sum=sum+t;
        count++;
        printf("是否继续?<yes···0/no···9>:");
        scanf("%d",&retry);
    }while(retry==0);
    prientf("和为%d,平均值为%.2f。\n",sum,(double)sum/count);
    return 0;
}

        下面我们来讲解一下求和的过程。

1准备

        首先进行求和的准备工作。假设变量count存储着读取的整数值的个数,变量sum存储着整数值的和,它们的初始值均为0.

2更新和及个数

        在循环体中,首先为变量t读入整数值。之后执行以下赋值。

        sum=sum+t;这里可以写成sum+=t;他和sum=sum+t是完全一样的效果,但是这种写法让代码看上去更简单,并且程序运行的时候不也不用那么麻烦,西面我们就直接用这种写法。

        count+=1;

        这样一来,count的值就会加1,从而变为1.

        接着,因为变量retry中读入的值为0,所以会再次执行循环体。

        只要retry中读入的值为0,上述处理就会一直循环进行。另外,每进行一次循环,变量count的值就加1,其中储存读入的数值个数。

复合赋值运算符

        上述2中使用的+=称为复合赋值运算符。这是一个同时进行加法运算+和赋值=的运算符。

         sum=sum+t和sum+=t几乎相同。

        包括+=在内,复合赋值运算符一共有10个。

后置递增迅运算符和后置递减运算符

        上述代码中使用的++是后置递增运算符。使用该运算符的表达式a++,能够使操作数的值仅加1。这种只增加1 的情况,我们称之为递增。

后置递增运算符a++使a的值增加1
后置递减运算符a--使a的值减少1

           如上表所示,使操作数的值减1(递减)的--运算符是后置递减运算符

        由于复合赋值运算符和后置递增运算符,后置递减运算符在一般的数学计算中不会使用,因此可能会觉得比较难。但熟悉之后,其实是很简单的。使用复合赋值运算符和后置递增运算符,后置递减运算符,能够使程序更简洁,更易读。

while语句

        与上一节介绍的do语句不同,在循环体执行前对循环的继续条件进行的判断是while语句。

        首先我们来写一串代码来看看while语句的执行过程。

        

//从输入的整数开始倒数到0
#include <stdio.h>
int main()
{
    int num;
    printf("请输入一个整数:");
    scanf("%d",&num);
    while(num>=0)
        {
            printf("%d",num);
            num--;
        }
        printf("\n");
    return 0;
}

        这里为了实现递减而使用了while语句。

        我们以num的值为5为例。

        首先对控制表达式num>=0的值进行判断,结果为1,不为0,所以循环体中的语句会被执行。先通过printf("%d",num);语句在屏幕上显示出5。接下来执行no--;语句,由于后置递减运算符的作用,num的值递减为4.

        这样循环体就结束了,程序会再次会到控制表达式。

        然后再对循环是否继续执行进行判断。由于表达式num>=0仍然成立,因此循环体会被执行。于是屏幕上会显示出4,并且num的值会递减为3。

        像这样,通过循环的反复执行,num的值会不断递减,并在屏幕上显示相应的数字。

        当num的值为0的时候,在屏幕上显示出0,接下来通过后置递减运算符使num的值递减为-1.在这之后判断循环是否继续执行的控制表达式num>=0就不再成立了,循环结束。

        需要注意的是,虽然最后显示在屏幕上的num的值是0,但其实while语句结束的时候它 的值已经变成了-1。

数据递增

        这次我们来编写一段跟之前的程序相反的程序,显示出从0开始递增到输入的整数的哥哥整数。程序代码如下图所示。

//递增显示从0到输入的正整数为止的各个整数
#include <stdio.h>
int main()
{
    int i,num;
    printf("请输入一个整数:");
    scanf("%d",&num);
    i=0;
    while(i<=num)
        {
            printf("%d",i++);
        }
        printf("\n");
    return 0;
}

        该程序与之前实现递减的程序最大的不同就是引入了一个新的变量i。i的值按照0,1,2···的方式递增。

限定次数的循环操作

        输入一个下整数后,并排显示出该整数个*,具体的程序代码如下图所示。  

//输入一个整数,连续显示出该整数个*
#include <stdio.h>
int main()
{
    int num;
    printf("正整数:");
    scanf("%d",&num);
    while(num-->0)
        {
            putchar('*');
        }
    putchar('\n');
    return 0;
}

        让我们以num的值等于15为例来考虑一下。首先,对while语句的控制表达式num-->0进行判断。--是后置递减运算符,所以会对递减前的num的值是否大于0进行判断。因此该控制表达式成立。之后,num的值递减,变为14。

        先这样,每当程序的流程经过控制表达式,num的值都会递减。当它的值递减为0时,表达式num-->0的值第一次为0,while语句也就结束了。另外,由于在判断的时候变量num的值会再次递减,因此while语句结束的时候num的值为-1。

字符常量和putchar函数

        在while语句执行的过程中,“putchar('*');”被执行;while语句结束之后,putchar('*');”。像'*'和'\n'这样,用单引号“”括起来的字符称为字符常量。字符常量是int型。

        为了显示单一的字符,本代码中使用了putchar函数。()中的实参,就是需要显示的字符。本代码中的参数是'*'和'\n'。后者会换行。

        注意:do语句的循环体至少会执行一次,而while语句的循环体则可能一次也不会执行。另外,在判断循环是否继续执行的时间方面,do语句和while语句也完全不同。

        1.do语句······先循环后判断:执行循环体之后的判断。

        2.while语句······先判断后循环:执行循环体之前进行判断。

▶下面要讲的for语句,也属于先判断后循环的类型。

逆向显示整数值        

        我们来考虑一下下面这个问题。

        输入一个非负整数,并进行逆向显示。

        也就是说,当输入1234的时候,显示出的结果是4321。当输入非正整数的时候,提示再次输入。我们来看看下面这串代码。

//逆向显示正整数
#include <stdio.h>
int main()
{
    int num;
    do{
        printf("请输入一个正整数:");
        scanf("%d",&num);
        if(num<=0)
            puts("\a请不要输入非正整数。");
       }while(num<=0)
    printf("该数逆向显示的结果是:");
    while(num>0)
        {
        printf("%d",num%10);
        num/=10;
        }
    puts("。");
    return 0;
}

        第一个do语句的作用是将输入的值限定为正值。当循环结束的时候,num的值肯定为正,即比0大。

        while语句的作用是将输入的整数逆向显示。假设num的值为1234,则最终结果就会显示4321。

        首先,先求出num%10的余数,也就是整数的最后一位数字,结果为4.然后执行以下语句。

        num/=10。

        由此可见,表达式num/=10的作用就是首先取出变量num的最后一位数字,然后将其他位的数字右移一位。

        因为num的值123大于0,所以会再次执行循环体。接下来显示123除以10的余数,然后用123除以10,变为12。

        只要num大于0,同样的处理就会循环执行,这样就完成了逆向显示的整个过程。

        当num的值为0的时候,控制表达式num>0就不成立,while语句也就执行结束了。

        以上是利用复合赋值运算符的第二个代码。复合赋值运算符有以下优点。

复合赋值运算符的优点

▶能够简洁地表示要进行的运算

        比起“将num除以10的商赋值给num”,“将num除以10”更加简洁,而且这种表达式也易于人们接受。

▶只需写一遍左边的变量名

        在变量名较长的情况下,或者在后面学习的使用数组和结构体的复杂的表达式中,使用复合赋值运算符能够减少输入错误,而且程序也更加易读。

▶左边的判断仅进行一次

        使用复合赋值运算符最大的好处就是左边的判断仅进行一次。在以后的学习中,该优势会更加明显。

for语句

        比起使用while语句,使用for语句实现循环会使程序更加简洁,易读。下面就来学习for语句。

for语句

        下面我们使用for语句对我们之前写的代码进行一下修改。

//递增显示从0到输入的正整数为止的各个整数
#include <stdio.h>
int main()
{
    int i,num;
    printf("请输入一个正整数:");
    scanf("%d",&num);
    for(i=0;i<=num;i++)
        {
            printf("%d",i);
        }
    printf("\n");
    return 0;
}

        程序变得更加简洁了。for语句的结构图如图所示。for语句后面的括号中由三部分构成,分别用分号隔开。

        用语言表述的话,就像下面这样。

        1.作为“预处理”,判断并执行A部分。

        2.如果作为“继续条件”的B部分控制表达式不为0,则执行语句(循环体)。

        3.执行语句后,判断并执行作为“收尾处理”或“下一个循环的准备处理”的C部分,返回到2

        关于for语句中的个表达式,有几点需要注意的地方。

        1.预处理

        表达式A仅在循环执行之前执行一次。当程序不需要预处理的时候,该表达式可以省略。

        2.控制表达式

        表达式B是用来判定循环操作是否继续执行的表达式。如果该表达式成立,则执行循环体。

        当省略表达式B的时候,通常认为控制表达式的值始终不为0。因此,除非使用break语句,否则该循环将成为永远执行的无限循环。

        3.收尾处理

        表达式C作为“收尾处理”或“下个循环的准备处理”,会在循环体执行后被判断,执行。如果没有需要执行的内容,则表达式可以省略。

使用for语句实现固定次数的循环

//输入一个整数,连续显示出整数个*
#include <stdio.h>
int main()
{
    int i,num;
    printf("正整数:");
    scanf("%d",&num);
    for(i=1;i<=num;i++)
        {
            putchar('*');
        }
    return 0;
}

        在上文使用了while与觉得代码程序中,变量num的值发生了变化。在循环的过程中,num的值一直在递减。在while语句结束的时候,num的值变为了-1。

偶数的枚举

        下面我们来编写一段程序,实现输入一个整数的值,显示该整数值一下的正偶数。                

//显示输入的整数值一下的偶数
#include <stdio.h>
int main()
{
    int i,num;
    printf("整数值:");
    scanf("%d",&num);
    for(i=2;i<=n;i+=2)
        {
            printf("%d",i);
        }
    return 0;
}

         for语句的i+=2部分中使用了复合赋值运算符+=,其作用是将右操作数的值加左操作数的值。

        因为是将变量i加2,所以每次循环时i的值都会加2。

约数的枚举

        下面我们来写一段程序,实现输入一个整数值,显示该整数值的所有约数。

//显示输入的整数值的所有约数
#include <stdio.h>
int main()
{
    int i,num;
    printf("整数值:");
    scanf("%d",&num);
    for(i=1;i<=num;i++)
        {
            if(num%i==0)
                printf("%d",i);
        }
    return 0;
}

        for语句中,变量i的值是从1到num递增的。

        如果num除以i的余数为0,则判断i是num的约数,并显示它的值。

循环语句

        本节学习的do语句,while语句,for语句,都是循环执行程序流程的语句。像这样的语句都称为循环语句

多重循环

        将循环语句的循环体作为循环语句,就可以进行二重,三重循环。这样的循环称为多重循环。下面我们来了解一下多重循环。

二重循环

        之前我们见到的程序中的循环,结构都比较简单。实际上,在一个循环中还可以嵌套另一个循环。根据所嵌套的循环的多少,有二重循环三重循环等。他们统称为多重循环

        使用二重循环显示九九乘法表的代码如下图所示。

//显示九九乘法表
#include <stdio.h>
int main()
{
    int i,j;
    for(i=1;i<=9;i++)
        {
            for(j=1;j<=i;j++)
                {
                    printf("%d*%d=%d\t",i,j,i*j);
                }

            printf("\n");
        }
    return 0;
}
                    

        外则的for语句的作用是使变量i的值从1到9递增。其循环分别对应乘法表的第1行,第2行·······,即纵方向的循环

        各行中执行的内则的for语句的作用是使变量j 的值从1到9递增,这是各行中的横方向的循环。 

显示图形

        下面我们来显示长方形。

//画一个长方形
#include <stdio.h>
int main()
{
    int i,j;
    int h,w;
    putf("让我们来画一个长方形");
    printf("高:");    scanf("%d",&h);
    printf("宽:");    scanf("%d",&w);
    for(i=1;i<=h;i++)
        {
            for(j=1;j<=w;j++)
                {
                    putchar('*');
                }
            printf("\n");
         }
    return 0;
}

        共计h行,每行都显示出w个*,这样就形成了一个长方形。

总结

1.do语句,while语句和for语句统称为循环语句。无论哪种循环语句,只要控制表达式的判断结果不为0,都要执行循环体。另外,循环语句的循环体也可以是循环语句。这种结构的循环语句是多重循环。

2.先循环后判断可以通过do语句来实现。循环体至少执行一次。即使是单一语句,也可以使之称为程序块,这样程序会更易读。

3.先判断后循环可以通过while语句和for语句来实现。循环体有可能一次也不执行。使用单一变量控制的固定类型的循环,可以通过for语句简单地实现。

4.循环语句中的break语句会中断该循环语句的执行。

5.表达式后带有分号的语句称为表达式语句。省略表达式,只有分号的表达式语句,称为空语句。

6.复合赋值运算符是既进行运算又进行赋值的运算符。与用两个运算符分别进行运算和赋值相比,使用复合赋值运算符可以使程序更简洁,而且对左操作数的判断仅需进行一次即可。

7.C语言程序的书写格式很自由。通过加入适当的缩进,可以使程序更易读。

  • 30
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值