C语言基础要素(016):入口条件循环:while与for

程序按照我们书写的顺序依次执行语句,称为顺序结构。根据条件,在多个语句序列间选择执行一种情况,属于分支结构。还有一类在满足某个条件之前反复执行语句的结构,称为循环(迭代)语句。假定现在要完成“重要的事情说三遍”这一壮举,我们可以这么做。

printf( "重要的事情说三遍!" );
printf( "重要的事情说三遍!" );
printf( "重要的事情说三遍!" );

万一重要的事情要喋喋不休说个千百遍呢?显然,我们需要有更有效的方式去完成这件事,这正是循环语句的用武之地。

while 循环语句

while语句的语法如下:

while (表达式)
    语句

在while循环语句中,首先对表达式求值。如果值为真,则执行语句;语句执行完成后,会再次求表达式的值,这一过程会一直进行下去,直到表达式求值为假,随后执行语句后面的部分。这种先判断再决定执行与否的循环,归属于入口条件循环

现在,重要的事情说几遍都是简单的事了。

#include <stdio.h>

int main()
{
    int i = 0;

    while (i < 3)
    {
        printf("重要的事情说三遍!\n");
        i++;
    }

    return 0;
}

在这里插入图片描述

这里i初值为0,while中的表达式是 i<3,也可以写为 i=1; i<=3。作为惯用法,迭代初始值通常从0开始,迭代范围采用的是上限不在其内原则,要让循环执行3次,迭代的范围是[0,3),即0、1、2;而不是[1,3],即1、2、3。另一方面,语句i++在完后一次迭代操作后让入口条件趋于束;否则程序会一直执行下去,形成死循环。

下面的例子展示了如何使用while循环,打印指定范围内的偶数。

#include <stdio.h>

int main()
{
    int pos = 0;
    int end = 127;
    int count = 0;

    while (pos < end)
    {
        if (pos % 2 == 0)
        {
            count++;
            printf("%d\t", pos);

            if (count % 10 == 0)
                printf("\n");
        }

        pos++;
    }

    return 0;
}

在这里插入图片描述

可以看出,建立一个重复执行固定次数的循环时涉及到三个动作。

  • 初始化:必须初始化一个计数器。
  • 测试:计数器与某个有限的值进行比较。
  • 更新:每执行完一次语句,计数器的值都要更新,向结束条件逼近。

for 循环语句

for是一种更易于使用的循环语句,语法如下:

for (表达式1; 表达式2; 表达式3)
    语句
  • 表达式1进行初始化,它在for循环开始的时候仅执行一次;
  • 表达式2是判断条件,在每次执行循环之前都要对它进行求值。当表达式为假时,循环就结了。
  • 表达式3进行改变或更新,它在每次循环结束时进行计算。
#include <stdio.h>

int main()
{
    for (int i = 0; i < 3; i++)
        printf("Hello!\n");
    return 0;
}

for语句将建立循环的三个动作初始化、测试、更新都放在了一起,它等价于下列的while语句:

表达式1
while (表达式2)
    语句
    表达式3

与while语句不同的是,在for语句头中定义的变量,其作域用仅在for语句中

#include <stdio.h>

int main()
{
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", i);   // 变量i的有效范围是整个for语句
    }

    printf("%d", i);        // Error:i在这里已经无效

    return 0;
}

在这里插入图片描述

for语句头的三个部分都是表达式,这很灵活,比如用逗号表达式完成整个初始化。

#include <stdio.h>

int main()
{
    for (int pos = 0, end = 200, count = 0; pos < end; pos++)
    {
        if (pos % 2 == 0)
        {
            count++;
            printf("%d\t", pos);

            if (count % 10 == 0)
                printf("\n");
        }
    }

    return 0;
}

甚至是输出一条信息…

#include <stdio.h>

int main()
{
    int a = 'a';
    int i = 0;

    for (a > 'b', printf("hello, world!\n"); i < 10; i++)
        printf("%d ", i);

    return 0;
}

在这里插入图片描述

示例有些偏于炫技,我们更偏向于将同种类型的操作放在初始化部分(像上面那样初始化三个相关的变量);而不是像这里,塞入一个关系比较、一个打印语句。for语句中所有表达式都可以省略,但表示语句的分号需要保留,我们逐步看看for退化为while的过程。首先省略掉第一个表达式,即初始化部分。

#include <stdio.h>

int main()
{
    int i = 0;
    for (; i < 10; i++)     // 省略掉第一个表达式,保留语法形式上的分号。
        printf("%d ", i);
    return 0;
}

接下来我们省略掉第三个表达式,这是计数器的更新部分。

#include <stdio.h>

int main()
{
    int i = 0;
    for (;i < 10;)        // 省略掉第3个表达式
    {
        printf("%d ", i);
        i++;               // 计数器更新部分挪到这里
    }

    return 0;
}

除去for头部因为语法需要的分号,几乎与while等价了。for的第二个表达式也可以省略,这表示判断条件永远为真,这就相当于 while (true),形成无限循环条件。

练习

  1. 改进打印指定范围内偶数的程序,让循环次数减半,更改范围进行测试。
  2. 使用for与while分别打印出 9, 8, 7, … 0 这些数值,除0外,数与数之间以逗号分隔。
  3. 尝试“忘记”编写循环的计数器更新部分,看看程序的表现,并找到结束程序的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值