了解可变范围

时间:2019-06-27 14:06:01

标签: c++

我对可变范围感到困惑,并希望更好地理解它。

将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不会保持适当的值。但是,事实恰恰相反,这引起了我的困惑。

3 个答案:

答案 0 :(得分:5)

您的代码具有未定义的行为(它包含一个错误),这意味着它可以执行任何操作。试图分析为何围绕更改输出移动语句或它们的[反-]直观性没有多大意义。

问题在于您的变量evenSoddS尚未初始化,并且您在写入变量之前先读取它们的值。读取未初始化的值是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";带入循环,则evenSoddS的值将被更频繁地打印。

答案 2 :(得分:-2)

这是Tutorials Point中范围的解释(方括号中的注释):

  

作用域是程序的一个区域,从广义上讲,可以在三个地方声明变量-

     
      
  1. 在称为局部变量的函数或块中。 [这里的块表示在这些括号{}上开始和结束的部分代码
  2.   
  3. 在功能参数的定义中,称为形式参数。
  4.   
  5. 被称为全局变量的所有函数之外。
  6.   
     

局部变量

     

在函数或块内声明的变量是局部变量。它们只能由该函数或代码块中的语句使用。 [如果您尝试通过任何一个编译器进行外部访问,都会给您一个错误。]

     

全局变量

     

全局变量是在所有函数之外定义的,通常在程序顶部。全局变量将在程序的整个生命周期内保持其值。

现在就按照您的情况说

  

将cout单数和cout偶数移到外部进行循环。代码执行   正确地。如果在for循环内移动,代码将使用不正确的值执行   表示单数和偶数。

如果在for循环内声明变量,则其作用域将保留在该块内(在该循环内)。