【问题标题】:Why is this C++ working? (declaration/definition of variables)为什么这个 C++ 工作? (变量的声明/定义)
【发布时间】:2021-05-13 09:09:41
【问题描述】:

为什么我可以在 for 循环的每次迭代中在 for 循环 [for (auto vall: k0L){...}] 中声明和定义 3 个变量?当我执行 g++ code.cpp 时,编译器不会抱怨。 我知道一个变量只能声明一次。 我知道我不能写 int a = 5; int a = 6;在 main() 范围内。 然而,这就是我在那个 for 循环中所做的。 谢谢!

#include <iostream>
#include <vector>
#include <fstream>
#include <math.h>
#include <algorithm>

#define PI 3.14159265

std::vector<double> linspace (double start, double end, size_t points) { // will be used in main(), details of this function are not important.
    std::vector<double> res(points);
    double step = (end - start) / (points - 1);
    size_t i = 0;
    for (auto& e: res) {
        e = start + step * i++;
    }
    return res;
}

int main() {

    std::vector<double> k0L = linspace (0,20, 10000); // a linearly spaced vector with 10000 values between 0,20
    std::vector<double> f_ra; 

    **// QUESTION : Why can I declare and define tau, phi_of_tau, to_push_back, at each iteration of the following for-loop?** 
    for (auto vall: k0L) {
        double tau = pow(vall, (1./3.)) * sin(20.0*PI/180.0);  // something1
        double phi_of_tau = 2.1 * tau * exp(- (2./3.) * pow(tau,3) );  // something2
        double to_push_back = 0.5 * pow(phi_of_tau, 2); // something_total, composed of something1 and something2
        f_ra.push_back(to_push_back); // equivalent to instruction below
        // f_ra.push_back(0.5 * pow(2.1 * (pow(vall, (1./3.)) * sin(30.0*PI/180.0)) * exp(- (2./3.) * pow((pow(vall, (1./3.)) * sin(20.0*PI/180.0)),3)), 2));    
    }

    // Write values to a file
    std::ofstream myfile("fra_vs_k0L_30degrees.dat");
    for (auto i=0; i<= f_ra.size(); i++) {
        myfile << k0L[i] << " " << f_ra[i] << std::endl;
    }

return 0;
} // END main()

【问题讨论】:

  • 那些变量声明了一次。声明是一段语法。
  • @StoryTeller-UnslanderMonica,谢谢。我会进一步阅读。

标签: c++ for-loop variables declaration stdvector


【解决方案1】:

这是由于范围。所有这些变量仅在 for 循环中可用。 如果你有这个代码

if(true) {
  int a = 1;
}
// notice a is not defined here, only in the if
if(true) {
  int a = 2;
}

它也不会抱怨。

【讨论】:

  • 非常感谢!
【解决方案2】:

因为这就是 C++ 中作用域的工作方式:这些变量的作用域是for 循环的主体。换句话说:它们是在每次循环迭代中创建的,并且一直存在到同一迭代结束。

完全等价于在函数内部声明局部变量,即使多次调用函数:

int f(int x) {
    int a = x * 2;
    return a;
}

int main() {
    f(2);
    f(2);
}

这当然不会让您感到惊讶,您不认为f 中的a 以某种方式重新定义了吗?

【讨论】:

  • 非常感谢!
【解决方案3】:

虽然与 for-loop 语法相关的其他答案是正确的,但我认为 OP 正在询问 C++11 基于范围的 for-loop 语法,这让他/她担心。

for (auto a : container) {...} 是 C++11 的基于范围的 for 循环语法,用于迭代 container 数据结构,每一步都引用 a,关键字 auto 的含义a 的类型将是 container 对象的类型。

更多详情可以在这里找到:https://en.cppreference.com/w/cpp/language/range-for

【讨论】:

  • 谢谢,其他答案回答了我的问题。我担心这些变量的声明——基本上我不认为变量在每次循环迭代后都会消失。
  • @velenos14,不客气。考虑接受其中一个答案。
  • 是的,系统允许我在2分钟左右完成
  • 啊,我忘了;)
【解决方案4】:

C++ 允许您在循环中声明/定义变量。变量的内存在循环开始时分配一次,因为这些变量是在循环中声明的,所以它们的范围仅限于该循环内。

这可能是一个很好的做法,因为限制变量的范围通常是正确的调用,并且使调试更容易。应该注意的是,变量不应该在循环之间保留它们的值,并且在您的具​​体示例中,它们的值每次都会重新初始化。由于您在初始化这些变量时发生了一些相当复杂的数学运算,因此这可能是对性能的有意义的消耗,因为这些计算是为了在每个循环中初始化变量而完成的。由于看起来这些变量保持恒定值,因此您最好在循环范围之外定义变量,以便计算只完成一次。希望对您有所帮助!

以下页面也很好地解决了这个问题:)

Declaring variables inside loops, good practice or bad practice?

https://softwareengineering.stackexchange.com/questions/296721/is-it-good-to-define-a-variable-inside-a-loop

【讨论】:

  • 非常感谢!变量的值在 for 循环的每次迭代中都会发生变化,因为在 for 循环的每次迭代中 vall 都是不同的。但我注意到并将记住您的信息@不必要的重复计算。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 2013-06-16
  • 2010-11-15
相关资源
最近更新 更多