首页 文章

C是否重制了循环中定义的变量?

提问于
浏览
0

当在C中的循环内声明变量时,C是否在循环的每次迭代中重制变量?我的意思是,它是否为另一个 num 变量重新分配内存?因此,如果循环迭代5次,你会得到5个独立的 num 变量及其自己的唯一值吗?在循环开始之前声明变量是一种更好的做法,即使该变量仅在循环内使用?如果我想将变量用作计数器或占位符怎么办?

// is this better code?
// int num;
for (int i = 0; i < 5; i++) {
  int num;
  // do stuff with num
}

4 回答

  • 2

    是的,如果 num 是循环内的定义,则每次循环运行时它将代表一个不同的变量 . 每次控件通过其定义时,它将被新初始化(如果有的话),并且每次循环的迭代结束时,它将被销毁 .

    通常应在尽可能最窄的范围内声明变量 . 因此,如果 num 不需要将其值从一次迭代保留到下一次迭代,则通常应在循环内定义 . 如果确实需要将其值从一次迭代保留到下一次迭代,则必须在循环外定义 .

    这种风格最佳实践有一些例外,例如初始化很昂贵 .

  • 5

    编译器可以优化内存使用,因此变量仅在物理上分配一次,然后在每次循环迭代时重用 . 但是,通常情况下,范围规则要求每个循环迭代都在变量的不同实例上运行 . 对于复杂类型(如类/结构),这意味着在每次循环迭代时调用变量上的构造函数和析构函数 .

  • 4

    这是一个新变量 . 您可以通过以下事实轻松地说服自己:

    for (int i = 0; i < 5; i++) {
      const int num = i;
      // do stuff with num
    }
    

    如果它真的是同一个变量,我们如何为常量变量分配新的东西?

    至于它是否在某种程度上更有效,你应该记住C有一个非常好的优化编译器 . 堆栈变量没有真正的“成本” . 一个简单的整数赋值显然没有任何副作用,因此编译器重用相同的空间是微不足道的 . 如果你不需要循环外的变量,最好在循环中声明它 .

    我建议使用https://gcc.godbolt.org/查看为一些小函数生成的程序集,无论是否进行优化,它都会让您了解编译器可以轻松优化的内容 .

  • 0

    在您概述的情况中,C标准指定变量的新实例在循环开始时构造,并在循环结束时销毁 .

    实际发生的事情,当你深入了解它的细节时,除此之外 . 允许C实现以它想要的任何方式实现它,只要可观察的结果是C标准规定的 .

    在这里,你只有一个朴素的花园品种 int . 虽然它正如我所描述的那样被正式构建和销毁,但是当构造和销毁变量时,实际上没有任何实质内容发生 . C不要求在本地范围内新构造的 int 被初始化为任何特定值 . 因此,在这种情况下,典型的C实现只是简单地将 int 分配给内存中的某个字段,并在每次循环迭代时使用它 .

    但是,如果你用一个更加充实的对象替换这个 int ,使用一个正式的构造函数,你会看到在循环迭代结束时(或者当执行线程离开循环时)对象's constructor will be obediently invoked at the beginning of every loop iteration, and the object'的析构函数将被顺从地调用范围) .

相关问题