当前位置: 首页 > news >正文

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. 尝试“忘记”编写循环的计数器更新部分,看看程序的表现,并找到结束程序的方法。

相关文章:

  • go 通过汇编分析栈布局和函数栈帧
  • SSM文物管理系统
  • chatgpt的一些prompt技巧
  • vue3设置全局滚动条样式
  • 1.5[hardware][day5]
  • 0CTF 2016 piapiapia 1
  • QT MVC 编程 MODEL/DELEGATE/VIEW(五)
  • day04_Java高级
  • OSPF与RIP联动实验
  • Java 并发编程——Java BIO NIO Socket编程
  • cursor全栈网页开发最合适的技术架构和开发语言
  • 进制转换(十进制相关)
  • 1.Qt SDK 的下载和安装
  • [Linux][经验总结]Ubuntu6.11.0 docker更换镜像源
  • Python3中的神秘错误:如何应对UnicodeDecodeError
  • CURL一文通
  • 考研系列-408真题计算机网络篇(10-17)
  • 《基于超高频RFID的图书馆管理系统的设计与实现》开题报告
  • HarmonyOS NEXT开发实战——HUAWEI DevEco Studio 开发指南
  • c++图论(二)之图的存储图解
  • 案件发回重审,李在明参选韩总统之路再添波折
  • 国家卫健委对近日肖某引发舆情问题开展调查
  • 摩天大楼天津117大厦复工背后:停工近十年,未知挑战和压力仍在
  • 人物|德国新外长关键词:总理忠实盟友、外交防务专家、大西洋主义者
  • 智能终端出海服务创新联合体成立
  • 解放日报社论:只争朝夕、不负重托,加快建成具有全球影响力的科技创新高地