变量的范围

Scope of variable

本文关键字:范围 变量      更新时间:2023-10-16

假设

while(1)
{
    {
        {
            int a=10;
            a=5;
        }
    }
}

现在,因为我不能在块的大括号后面引用"a"。我想知道何时控件向上移动到第一个大括号,然后向下运行访问的第三个大括号将再次声明"a"或"a"保持值5。

循环的每一步都将定义一个新的a变量。

a只有在声明时才会声明…

您在内部作用域内声明了它,因此任何引用a的代码都只能在同一作用域内有效。一旦你离开了这个范围,你的程序中就再也不存在名为"a"的东西了。用于保存值5的存储器现在可以由程序的其余部分用于其他目的。

从逻辑上讲,a不能在其声明之前或在其声明的大括号对结束之后被引用。它也会在结束时被销毁,但这对int来说是一个NOP。每次循环时,它都将被重新初始化为10。

但是,你错过了问题中有趣的部分,即如果声明没有设置值会发生什么:

while(1)
{
        {
            int a;    // Here Scope Starts  
            a=5;
        }// Here Scope Ends
}

这里,a在第一次设置之前将是未定义的。但是,它也几乎总是在堆栈上的同一位置,因此,如果没有其他东西使用该空间,它可能会在一次迭代到下一次迭代中保留值。但它是否执行可能取决于执行,这使得它成为一个令人兴奋的bug来源。

while(1)
{
    {
        {// Here Scope Starts
            int a=10;      
            a=5;
        }// Here Scope Ends
    }
}

每次迭代都会在堆栈上逻辑地重新分配变量——实际上,内存位置只会被重用。但请注意,在您的琐碎示例中,当循环在下一次迭代中返回声明时,"a"的值永远不会"明显"保持"5"的值,因为在声明时它被显式初始化为"10"。如果C#遵循与Java相同的做法,那么如果编译器没有首先抱怨如果您自己不初始化未初始化的变量,则它将隐式地重新初始化为默认值。

while循环的每次迭代,您都会定义新的变量a,"a"的值也会更改,但如果以任何方式循环结束,您将丢失这个变量(即使在同一函数中也不能使用它)!!

a将被再次声明。

如果您确实希望参数重置每个循环,那么您通常会在循环中将其定义为a,这样就不会在迭代之间携带值。

while(1)
{
    {
        {
            //Define a new `a`
            int a=10;
            a=5;
        }
    }
}

但是,如果您希望在所有迭代中使用相同的参数和值,则需要在循环外定义它:

int a=0;
while(1)
{
    {
        {
            //`a` will count the number of iterations.
            a = a + 1;
        }
    }
}