简体   繁体   English

我想确认我对变量范围的理解在C ++中是正确的

[英]I want to confirm that my understanding of variables scope is correct in C++

I have read about scope and have thought that I understood it up to now. 我已经阅读了关于范围的内容,并且认为我到目前为止已经理解了它。 I had a problem with another program and while trying to fix it I found that variables in the scope of a loop behave quite unusually to what I expected. 我遇到了另一个程序的问题,在尝试修复它时,我发现循环范围内的变量表现得非常不符合我的预期。 So I made this program to show what I mean: 所以我制作了这个节目来表明我的意思:

#include <iostream>

using namespace std;

int main()
{
    int num = 6;
    for (int i = 0; i < 5; i++)
    {
        cout << num;
        int num = 5;
        cout << num;
    }
}

I expected for the first run through of the for loop, the first cout << num would be undefined as it is a new scope and num hasn't been defined yet. 我期望首次运行for循环,第一个cout << num将是未定义的,因为它是一个新的范围,而num尚未定义。 But instead, it just used the value of num from the previous scope. 但相反,它只使用了前一个范围的num值。 Then when num is initialized to 5 inside of the loop, after that, all the outputs for num should be 5. But instead the output was 656565... 然后当num在循环内部被初始化为5时,之后,num的所有输出应该是5.但是输出是656565 ......

So using this information I made a model of what I think the scope of variables worked like and it looks like this: 因此,使用这些信息,我建立了一个模型,我认为变量的范围就像它一样,它看起来像这样:

范围图

So in the image you can see how I think the scope works and I think that for each iteration through the loop, the loop gets a new scope of variables and then removes its scope at the end of the loop and gets a new one at the beginning of the next iteration which explain why the for loop uses num from the previous scope until num is re-initialized in the current scope. 所以在图像中你可以看到我认为范围是如何工作的,我认为对于循环中的每次迭代,循环获得一个新的变量范围,然后在循环结束时删除它的范围并获取一个新的范围。下一次迭代的开始,解释为什么for循环使用前一个范围中的num,直到num在当前范围内重新初始化。 Is my understanding correct? 我的理解是否正确?

Is my understanding correct? 我的理解是否正确?

Yes but num is not re-initialized . 是,但num 不会 重新初始化 It defines another variable. 它定义了另一个变量。
"inner" num shadows the "outer" num . “inner” num 遮蔽 “外部” num

Since both num s have block scope , as per basic.scope.block : 由于两个num都有块范围 ,因为basic.scope.block

A name declared in a block is local to that block; 块中声明的名称是该块的本地名称; it has block scope . 它有块范围 Its potential scope begins at its point of declaration and ends at the end of its block . 它的潜在范围从其声明点 开始 ,并在其块 结束结束 A variable declared at block scope is a local variable. 在块作用域中声明的变量是局部变量。

int main() {
   int num = 6; // block scope (a) ---- point of declaration for (a) begins
   for (int i = 0; i < 5; i++)
   {
      cout << num; // uses (a)
      int num = 5; // block scope (b) ---- point of declaration for (b) begins
      cout << num; // uses (b)         ||
   }               //                 ---- (b) goes out of scope here
} // ---- (a) goes out of scope here

Your diagram is correct if scope 1 is the most outer scope and scope 4 is the most inner scope. 如果范围1是最外部范围并且范围4是最内部范围,则图表是正确的。 Your use of the word "overwritten" is not the convention for C++. 使用“覆盖”一词不是C ++的惯例。 The variables are not overwritten but rather shadowed . 变量不会被覆盖,而是被遮蔽 Similar shadowing is part of many programming languages. 类似的阴影是许多编程语言的一部分。

I expected for the first run through of the for loop, the first cout << num would be undefined as it is a new scope and num hasn't been defined yet. 我期望首次运行for循环,第一个cout << num将是未定义的,因为它是一个新的范围,而num尚未定义。 But instead, it just used the value of num from the previous scope. 但相反,它只使用了前一个范围的num值。 Then when num is initialized to 5 inside of the loop, after that, all the outputs for num should be 5. But instead the output was 656565... 然后当num在循环内部被初始化为5时,之后,num的所有输出应该是5.但是输出是656565 ......

Your understanding here is incorrect, and the output you are seeing is correct. 您在此处的理解不正确,您看到的输出是正确的。

Within the loop, the first cout << num will print the variable num that was defined before the loop. 在循环中,第一个cout << num将打印在循环之前定义的变量num The second will print the variable that was defined inside the loop. 第二个将打印循环内定义的变量。

The int num = 5 in the loop does not affect the previously defined variable (in the outer scope). 循环中的int num = 5不会影响先前定义的变量(在外部作用域中)。 It defines a completely new variable, and initialises that to 5 . 它定义了一个全新的变量,并将其初始化为5 There is no impact whatsoever on the value of the num that was defined before the loop. 对循环之前定义的num的值没有任何影响。 Therefore the num defined outside will keep the value 6 , and the one defined inside (created in every loop iteration) will have the value 5 . 因此,外部定义的num将保持值6 ,而内部定义的num (在每次循环迭代中创建)将具有值5 Although your code gives them the same name ( num ) they are completely distinct variables, and occupy different addresses in memory - so changing one does not change the other. 尽管您的代码为它们指定了相同的名称( num ),但它们是完全不同的变量,并且在内存中占用不同的地址 - 因此更改一个不会改变另一个。

Practically your code 实际上你的代码

 int num = 6; for (int i = 0; i < 5; i++) { cout << num; int num = 5; cout << num; } 

is notionally equivalent to 在概念上等同于

int num = 6;
for (int i = 0; i < 5; i++)
{
    cout << num;
    {                   //  note another scope introduced here
        int num = 5;
        cout << num;
    }
}

This notional equivalence results from requirements in a standard that, if multiple variables of automatic storage duration are created in a block, that they cease to exist in reverse order of their order of construction. 这种概念等价来自标准中的要求,如果在块中创建自动存储持续时间的多个变量,则它们不再以其构造顺序的相反顺序存在。 (ie if you track calls of constructors and destructors of class objects, the most recently constructed object of automatic storage duration will be destructed first). (即,如果跟踪类对象的构造函数和析构函数的调用,则最先构造的自动存储持续时间对象将首​​先被破坏)。

The cout statements cannot access a value of num unless it is in the current scope or in a containing scope. 除非cout语句位于当前作用域或包含作用域中,否则cout语句不能访问num的值。 Viewing it this way, therefore, means that the first cout << num only has visibility of the outer num (the one initialised to 6 ) and not the inner one. 因此,以这种方式查看意味着第一个cout << num仅具有外部num (初始化为6 )而不是内部num可见性。 Whereas the second cout << num accesses the variable defined in the inner scope. 而第二个cout << num访问内部范围中定义的变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM