我对可变范围感到困惑,并希望更好地理解它。
将cout单数和cout偶数移到外部进行循环。代码正确执行。如果将其移入for循环,则代码会以不正确的ods和evenS值来执行。
#include <iostream>
#include <vector>
#include <cmath>
int main()
{
double evenS, oddS, pH = 0;
std::vector<double> v1 = {2, 4, 3, 6, 1, 9};
for(int i = 0; i < v1.size(); i++)
{
pH = v1[i];
if(fmod(pH, 2) == 0)
{
evenS = evenS + v1[i];
}
else if(fmod(pH, 2) == 1)
{
oddS = oddS + v1[i];
}
}
std::cout << evenS << "\n";
std::cout << oddS << "\n";
}
我期望如果在for循环之外递增,odds和evenS不会保持适当的值。但是,事实恰恰相反,这引起了我的困惑。
答案 0 :(得分:5)
您的代码具有未定义的行为(它包含一个错误),这意味着它可以执行任何操作。试图分析为何围绕更改输出移动语句或它们的[反-]直观性没有多大意义。
问题在于您的变量evenS
和oddS
尚未初始化,并且您在写入变量之前先读取它们的值。读取未初始化的值是UB。
您可能打算将其写为定义:
double evenS = 0, oddS = 0, pH = 0;
要在声明中声明的每个变量都需要有自己的初始化程序。
答案 1 :(得分:0)
正如@Angew所提到的,您的代码中有一个错误,他建议您进行修复。以下主题有助于理解未初始化的值:What happens to a declared, uninitialized variable in C? Does it have a value?
对于变量作用域,如果将std::cout << evenS << "\n";
和std::cout << oddS << "\n";
带入循环,则evenS
和oddS
的值将被更频繁地打印。
答案 2 :(得分:-2)
这是Tutorials Point中范围的解释(方括号中的注释):
作用域是程序的一个区域,从广义上讲,可以在三个地方声明变量-
- 在称为局部变量的函数或块中。 [这里的块表示在这些括号
{}
上开始和结束的部分代码- 在功能参数的定义中,称为形式参数。
- 被称为全局变量的所有函数之外。
局部变量
在函数或块内声明的变量是局部变量。它们只能由该函数或代码块中的语句使用。 [如果您尝试通过任何一个编译器进行外部访问,都会给您一个错误。]
全局变量
全局变量是在所有函数之外定义的,通常在程序顶部。全局变量将在程序的整个生命周期内保持其值。
现在就按照您的情况说
将cout单数和cout偶数移到外部进行循环。代码执行 正确地。如果在for循环内移动,代码将使用不正确的值执行 表示单数和偶数。
如果在for循环内声明变量,则其作用域将保留在该块内(在该循环内)。