为什么 for/while/do-while 在执行相同的任务时被放置在 c/c++ 中

Why for/while/do-while were placed in c/c++ when they perform same task

本文关键字:c++ 任务 while for do-while 执行 为什么      更新时间:2023-10-16

为什么在 c/c++ 中需要 3 个不同的循环:"while"、"do-while"和"for",尤其是当它们中的每一个都让你有能力做其他 2 个几乎可以做的任何事情时?其他语言缺少其中一种。

它只是为了易于使用还是为了使代码在案例中看起来更好,或者是否有任何特殊目的,其中任何一个专门服务于其他两个无法轻松完成?如果是,那么请提及。

附言:一般来说,一种语言是否支持许多迭代语法只是为了增强可读性?

它不仅仅是可读性,它也是密切相关但独特的可维护性、简洁性和范围(尤其是文件、锁、智能指针等(和性能......

如果我们考虑for循环,它:

  • 允许在for循环自己的范围内定义一些变量并初始化,

  • 每次进入循环之前测试控制表达式(包括第一次(,以及

  • 有一个语句,该
  • 语句在每次迭代之后和重新测试控制表达式之前执行,假设没有break/return/throw/exit/失败assert等,也不管是执行了主体中的最后一个语句还是执行了continue语句; 该语句传统上保留用于逻辑"推进"某些状态"通过"处理, 这样,控件表达式的下一个测试是有意义的。

这是非常灵活的,并且考虑到更本地化的作用域的实用性来确保更早的析构函数调用,可以帮助确保锁、文件、内存等尽早释放 - 在离开循环时隐式释放。

如果我们考虑一个while循环...

while (expression to test)
    ...

。它在功能上完全等同于...

for ( ; expression to test; )
    ...

。但是,这也向程序员暗示,没有控制变量应该是循环局部的,并且控件"要测试的表达式"本质上"进展"通过有限次数的迭代,如果测试表达式是硬编码的,则永远循环true,或者更复杂的"进度"管理必须由while控制的语句自己控制和协调。

换句话说,程序员看到while会自动意识到他们需要更仔细地研究控件表达式,然后可能更广泛地查看周围的范围/函数和包含的语句,以了解循环行为。

那么,do - while?好吧,编写这样的代码是痛苦的,效率较低:

bool first_time = true;
while (first_time || ...)
{
    first_time = false;
    ...
}
// oops... first_time still hanging around...

。相比...

do
    ...
while (...);

例子

而循环:

int i = 23;
while (i < 99)
{
    if (f(i)) { ++i; continue; }
    if (g(i)) break;
    ++i;
}
// oops... i is hanging around

对于循环:

for (int i = 23; i < 99; ++i)
{
    if (f(i)) continue;
    if (g(i)) break;
}

好吧,C++有goto,你可以用它来实现所有三个循环,但这并不意味着应该删除它们。实际上,它只是增加了可读性。当然,您可以自己实现其中任何一个。

有些循环用for最容易写,有些用while最容易写,有些用do-while最容易写。 因此,该语言提供了所有三个。

出于同样的原因,我们有像+=运算符这样的东西; += 不会做任何你不能用普通+做的事情,但使用它(在适当的情况下(可以使你的代码更具可读性。

通常,当呈现实现类似目的的不同语言结构时,您应该选择更清楚地传达您正在编写的代码的预期目的的语言结构。C 提供了四种不同的结构化迭代设备供使用,这是一个好处,因为它提供了很高的机会,您可以清楚地传达预期目的。

for (初始化;条件;迭代步骤)

这种形式传达了循环将如何开始,它将如何为下一次迭代调整内容,以及保持循环中的条件是什么。这种结构自然适合在N时候做某事。

    for (int i = 0; i < N; ++i) {
        /* ... */
    }

身体) while (状况

此表单仅传达您希望在条件保持为真时继续执行循环。对于迭代步骤隐含到循环工作方式的循环,它可以是传达代码意图的更自然的方式:

    while (std::cin >> word) {
        /* ... */
    }

do身体while (状况)

此窗体表示循环体将至少执行一次,然后在条件保持为真时继续执行。这对于您已经确定需要执行正文的情况很有用,因此您可以避免多余的测试。

    if (count > 0) {
        do {
            /* ... */
        } while (--count > 0);
    } else {
        puts("nothing to do");
    }

第四个迭代设备是...递归!

递归是另一种形式的迭代,它表示相同的函数可用于处理原始问题的较小部分。这是一种自然的方式来表达对问题的分而治之策略(如二分搜索或排序(,或者处理自我引用的数据结构(如列表或树(。

struct node {
    struct node *next;
    char name[32];
    char info[256];
};
struct node * find (struct node *list, char *name)
{
    if (list == NULL || strcmp(name, list->name) == 0) {
        return list;
    }
    return find(list->next, name);
}