for循环带来的内部变量重置

1. 问题

先放一段错误的代码:

sum变量并不能实现5组输出后换行

#include <stdio.h>
#include <math.h>

int main()
{
    printf("101 to 200 prime numbers:\n");
    for (int i = 101; i <= 200; i++)
    {
        int sum = 0;
        if (func_number(i))
        {
            printf("%d\t", i);
            sum++;
            if ((sum % 5 == 0))
            {
                printf("\n");
            }
        }
    }
    return 0;
}

int func_number(int n)
{
    int flag = 1;
    for (int i = 2; i <= sqrt(n); i++)
    {
        if (n % i == 0)
        {
            flag = 0;
            return flag;
        }
    }
    return flag;
}

2. 错误分析

2.1 作用域

在 C 语言中,变量的作用域决定了它在哪里可以被访问。如果变量是在一个代码块(如 for 循环、if 语句或函数体)内部声明的,那么它的作用域就限制在那个代码块内。在原始代码中,sum 是在 for 循环的初始化部分声明的,因此它的作用域仅限于那个 for 循环的迭代。

2.2 生命周期

变量的生命周期是指变量存在的时间。对于在函数内部声明的局部变量(如 sum),它们的生命周期从声明点开始,到包含它们的函数返回时结束。但是,在循环内部声明的变量(尽管它们的作用域可能只限于循环体,但在这个特定情况下,由于是在循环的初始化部分声明的,所以实际上它们是在循环开始之前声明的),它们的生命周期贯穿整个包含它们的函数或代码块,但它们的值会在每次循环迭代时根据需要进行重新初始化或更新。

然而,在原始代码中,sum 的值被错误地“重置”了,因为虽然它的生命周期贯穿整个 for 循环,但由于它是在循环的初始化部分声明的,所以每次循环开始时,它都会被重新初始化为 0。这实际上并不是“重置”的通常含义(即改变一个已经存在的变量的值),而是每次循环迭代时都创建了一个新的 sum 变量(尽管在内存中的位置可能相同,但从逻辑上讲,它是新的),并将其初始化为 0。

2.3 解决方案

为了解决这个问题,需要将 sum 的声明和初始化移出 for 循环,这样它就可以在整个 main 函数中保持其值,并在每次循环迭代时递增,而不是被重置。这就是我在之前的回答中所做的修改。

2.4 总结

  • sum 的作用域原本被限制在 for 循环内,但由于它是在循环的初始化部分声明的,所以实际上它的作用域贯穿了整个 main 函数(尽管逻辑上它只在循环内被使用)。
  • sum 的生命周期也贯穿了整个 main 函数,但由于它在循环内部被重新初始化,所以每次循环迭代时它都“看起来像是”被重置了。
  • 通过将 sum 的声明和初始化移出 for 循环,可以确保它在整个函数中保持其值,并在需要时递增。

3. 思考

在 C 语言中,for 循环内部使用的变量(如 i)为什么不重置。

对于 for 循环中的变量 i,如果它是在 for 循环的初始化部分声明的(如 for (int i = 0; i < n; i++)),那么它的作用域就限制在 for 循环体内。这意味着 i 只能在 for 循环的迭代中被访问和修改。

生命周期

然而,尽管 i 的作用域被限制在 for 循环内,它的生命周期却贯穿了整个 for 循环的执行过程。这意味着 i 的存在从 for 循环开始之前(在初始化部分被创建和初始化)一直持续到 for 循环结束。在每次循环迭代中,i 的值会根据循环的控制表达式进行更新(在这个例子中是递增)。

为什么 i 不会重置?

i 不会在每次循环迭代时“重置”,而是会根据循环的控制表达式进行更新。在 for (int i = 0; i < n; i++) 这样的循环中,i 在循环开始前被初始化为 0,然后在每次迭代结束时递增(i++)。这个递增操作确保了 i 的值在每次迭代时都是唯一的,并且根据循环的进度逐渐增加,直到达到或超过 n,此时循环终止。

与 sum 的比较

与 sum 不同,sum 在您的原始代码中是在循环内部声明的,并且由于它被放在了循环的初始化部分(尽管不是循环控制的一部分),它实际上是在每次迭代时都被重新声明和初始化(尽管在物理内存上可能是在同一个位置)。但是,由于 C 语言的语法规则,i 的声明是作为 for 循环的一部分,因此它只被声明一次,并在整个循环过程中保持其值,直到循环结束。

结论

因此,i 不会在每次循环迭代时重置,而是会根据循环的控制表达式进行更新。而 sum 之所以在您的原始代码中“重置”,是因为它被错误地放在了循环的初始化部分,导致它在每次迭代时都被重新声明和初始化。通过将 sum 的声明移出循环,您可以确保它在整个循环过程中保持其值,并在需要时递增。

  • 24
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工大老张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值