【问题标题】:Understanding Variable Scope了解变量范围
【发布时间】:2019-06-27 14:06:01
【问题描述】:

我对变量范围感到困惑,想更好地理解它。

将 cout oddS 和 cout evenS 移到 for 循环之外。代码正确执行。如果移到 for 循环内,代码会使用不正确的奇数和偶数值执行。

#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";
}

如果oddS 和evenS 在for 循环之外增加,我预计不会保持正确的值。然而,事实恰恰相反,这引起了我的困惑。

【问题讨论】:

  • 如果您可以通过正确格式化括号来说明范围会更容易。通过 TAB 键输入缩进。每个新的括号是一个制表符。

标签: c++


【解决方案1】:

你的代码有未定义的行为(它包含一个错误),这意味着它可以做任何事情。试图分析为什么移动语句会改变输出,或者它们是多么[反]直觉,是没有意义的。

问题在于您的变量evenS 和oddS 未初始化,并且您在写入它们之前正在读取它们的值。读取未初始化的值是 UB。

你可能打算把这个写成定义:

double evenS = 0, oddS = 0, pH = 0;

如果要在声明中声明的每个变量都需要自己的初始化器,则它需要一个。

【讨论】:

  • 感谢您的解释。我已经改进了这段代码以正确初始化变量。我会确保在未来使用它。我的问题源于将oddS 和evenS 上的cout 语句上移一个括号。我的印象是,如果我在 for 语句中更改这些变量,然后在 for 之外计算变量,它们将不会输出正确的值。也许我对函数如何返回值感到困惑。我相信我现在已经弄清楚了。感谢您的宝贵时间。
  • @wiregh0st 变量在其整个生命周期内(从创建/初始化到销毁)都保持其值,即使控制流在此期间进入(并随后离开)其他范围。
  • @wiregh0st "我的印象是,如果我在 for 语句中对这些变量进行更改,然后在 for 之外计算变量,它们将不会输出正确的值。” 不。变量要么在范围内,要么不在。当您点击不相关的} 时,它的值不会消失。 “也许我对函数返回值的方式感到困惑”同样的故事
【解决方案2】:

正如@Angew 提到的,您的代码中有一个错误,他建议修复。以下主题有助于理解未初始化的值:What happens to a declared, uninitialized variable in C? Does it have a value?

对于变量作用域,如果将std::cout &lt;&lt; evenS &lt;&lt; "\n";和std::cout &lt;&lt; oddS &lt;&lt; "\n";带入循环,evenS和oddS的值会被更频繁地打印出来。

【讨论】:

    【解决方案3】:

    以下是来自Tutorials Point 的范围解释(方括号中的注释):

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

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

    局部变量

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

    全局变量

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

    现在就像你说的那样

    将 cout oddS 和 cout evenS 移到 for 循环之外。代码执行 适当地。如果移入 for 循环,代码会以不正确的值执行 奇数和偶数。

    如果你在 for 循环中声明变量,它的作用域将保持在那个块内(在那个循环内)。

    【讨论】:

    • 不正确。如果变量超出范围,尝试从中读取将编译失败,而不是“打印一些垃圾值”。
    • 剩下的答案只是从另一个网页复制/粘贴无关紧要
    • 是的,我的错误垃圾不应该打印,我编辑了我的答案
    • 它没有完全复制,我修改了它来解释,甚至我也提到了参考,这就是为什么你拒绝投票,因为我提到了参考? :) 最糟糕的。
    • 哦,是的,您确实添加了两个小注释。但是你不能把别人的话当作你自己的话。那不行。答案中的 only 原创作品不正确,按照我已经解释的方式,因此投反对票。这个答案的当前形式在技术上不再是不正确的,但仍然没有实质性。 “它的范围将保持在该块内”这如何回答这个问题?它根本没有解决问题。
    猜你喜欢
    • 2015-05-02
    • 1970-01-01
    • 2011-04-15
    • 2014-04-18
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    相关资源
    最近更新 更多