为什么我可以在for循环中声明和定义3个变量[for (auto vall: k0L){…}],在for循环的每次迭代时?当我执行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()
因为c++中的作用域就是这样工作的:这些变量的作用域是for
循环体。换句话说:它们在每个循环迭代中创建,并且一直存在到同一迭代结束。
这完全等同于在函数内部声明局部变量,即使你多次调用一个函数:
int f(int x) {
int a = x * 2;
return a;
}
int main() {
f(2);
f(2);
}
这当然不会让你感到惊讶,你不认为f
中的a
在某种程度上被重新定义了吗?
这是由于范围。所有这些变量只能在for循环中使用。如果你有这样的代码
if(true) {
int a = 1;
}
// notice a is not defined here, only in the if
if(true) {
int a = 2;
}
它也不会抱怨。
c++允许在循环中声明/定义变量。变量的内存在循环开始时分配一次,因为这些变量是在循环中声明的,所以它们的作用域被限制在该循环内。
这可能是一个很好的实践,因为限制变量的范围通常是正确的调用,并且使调试更容易。应该注意的是,变量不希望在循环之间保留它们的值,并且在您的特定示例中,它们的值每次都被重新初始化。由于需要进行一些相当复杂的数学运算来初始化这些变量,这可能会对性能造成很大的影响,因为这些计算是在每个循环中初始化变量的。因为看起来这些变量保存常量值,所以在您的情况下,最好在循环作用域之外定义变量,这样计算只完成一次。希望这对你有帮助!
下面几页也很好地解决了这个问题:)
在循环中声明变量,好习惯还是坏习惯?
https://softwareengineering.stackexchange.com/questions/296721/is-it-good-to-define-a-variable-inside-a-loop
虽然与for循环语法相关的其他答案是正确的,但我认为OP正在询问有关c++ 11的基于范围的for循环语法,这使他/她担心。
这个for (auto a : container) {...}
是c++ 11的基于范围的for循环语法,它用于在container
数据结构上迭代,每一步引用a
,关键字auto
意味着a
的类型将是container
对象的类型。
更多细节可在这里找到:https://en.cppreference.com/w/cpp/language/range-for