在 for 循环之外初始化计数器无法按预期工作

initializing counter outside for loop doesn't work as intended

以下两个程序应该生成 1、2、3 的所有三个数字组合(重复)。它们在各个方面都是相同的,除了初始化循环计数器的地方

#include <stdio.h>
int main(void)
{
        short i, j, k;
        i = j = k = 1;
        for (; i <= 3; i++) {
                for (; j <= 3; j++) {
                        for (; k <= 3; k++)
                                fprintf(stdout, "%hi %hi %hi\n", i, j, k);
                }
        }
        return 0;
}

...这三个循环的计数器在它们之外初始化的那个不会产生所需的输出。它打印出来。

1 1 1
1 1 2
1 1 3

第二个...

#include <stdio.h>
int main(void)
{
        short i, j, k;
        for (i = 1; i <= 3; i++) {
                for (j = 1; j <= 3; j++) {
                        for (k = 1; k <= 3; k++)
                                fprintf(stdout, "%hi %hi %hi\n", i, j, k);
                }
        }
        return 0;
}

...在每个循环中初始化计数器,产生所需的输出

1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3

在一本书中读到,for 循环可以用多种形式编写——所有形式都是相同的——并且可以在 for 语句内部或外部初始化、递增、测试计数器。那为什么这里有不同的行为?

在第二个中,每次遇到for循环时,变量j和k都重新初始化为1。

在第一个中,它们总是只剩下它们的值——这意味着第二轮(当 i == 2 或 3 时),j 从第一轮开始留在 4,这立即使 j <= 3 条件失败。

这与如何初始化 for 循环无关,而是每次启动 for 循环时都不会初始化它。

        for (; i <= 3; i++) {
            for (; j <= 3; j++) {
                    for (; k <= 3; k++)

所以第一次没问题,因为值是正确的,但是在第二个和第三个 for 循环完成迭代并且第一个 for 循环到达第二个索引后,另一个 for 循环没有被初始化,所以它们的值保持不变4 并且不满足条件,因此循环就此停止。 您仍然需要在嵌套的 for 循环中使用初始化来解决问题。

因为您没有在循环内初始化变量 i, j, k 而是在外部作用域中定义它们,所以它们的值保持不变。

特别是k仍然是4,在第一个循环结束到运行之后,那么条件k<=3总是假的,永远不会到达打印语句。

以与您的书相同的方式编写代码的意思是这样的:

#include <stdio.h>
int main(void)
{
        short i, j, k;
        i = 1;
        for (; i <= 3; i++) {
                j = 1;
                for (; j <= 3; j++) {
                       k = 1;
                        for (; k <= 3; k++)
                                fprintf(stdout, "%hi %hi %hi\n", i, j, k);
                }
        }
        return 0;
}

如果您只在 for 循环之外初始化您的变量一次,那么它们的值将永远不会在嵌套循环中获得 re-initialized(生成以 [ 开头的每个组合所需的东西) =11=]、2xx3xx).

在外部初始化的情况下: 在生成所有 11x 组合后,您的 k 变量将具有值 4,无论封闭循环做什么。

因此,当 ji 递增到 23 时,您的 k 将已经是 4,因此最里面的 for 循环将不再执行。

不用说,您的代码的第二个变体,re-initializes kj 每次 i 递增,这将使您的代码达到 printf 每次都如您所愿。