嵌套代码块和作用域

本节课其实前面的课程中又讲到过,不过我们本节通过内存的存储来再次加深理解。

本教程来自foxdevelop.com,转载请标明出处。

方法体内可以嵌套其他代码块。

class Program
{
    static void Main()
    {
        int age = 19;
        {
            int one = 23;
        }
    }
}
Code language: C# (cs)

代码块数量不限,可顺序排列,也可多层嵌套,无层级限制。

class Program
{
    static void Main()
    {
        int age = 19;
        {
            int one = 23;
            {
                int two = 45;
                {
                    int three = 56;
                }
            }
        }
    }
}Code language: C# (cs)

注意,子嵌套块上面的int xxxx = xxx;这个是和它并列的语句。

如上面int age = 19; 和下面的嵌套代码块是并列的两个语句,千万不要把它当成了方法体。


生命周期

看一个例子

    static void Main()
    {
        int a = 10;
        {
            int b = 20;
        }
    }Code language: C# (cs)

这个例子中,有两个局部变量,最外面的a属于Main函数的最外面的,b属于子嵌套代码块的。

下面分步执行,看栈内存是如何存储的。

第一步:仅执行int a = 10;,栈分配a空间,值为 10;

第二步:进入内层块执行int b = 20;,栈新增b,栈结构从上至下:b、a;

第三步:内层代码块执行完毕,b从栈弹出,栈仅保留a

第四步:Main方法执行完毕,a从栈弹出,本程序所有变量都销毁,程序执行结束。

总结

在嵌套块内部声明,生命周期从声明处开始,到所属代码块结束为止。

程序嵌套块执行完毕时,该块内所有局部变量会从栈中弹出销毁

对于方法体,其实也是一个大的代码块


作用域

只要第一个变量的作用域还存在,无论嵌套多少层,都不能再声明同名局部变量。

看例子

    static void Main()
    {
        int a = 10;
        {
            int a = 20;
        }
    }Code language: C# (cs)

上面例子,里面的子嵌套代码块,的变量a和外面的a同名了。这时候是出错的,编译都无法通过。

原因是:对于外面的int a = 10;的作用域是它所在的代码块,也就是int a = 10;的上一级{ } 大括号内,在这个作用域里面,不允许出现和a同名的变量。上面的int a = 20; 尽管是在一个嵌套的代码块里面,但是它本身也属于方法体里面的,因为int a = 10; 是在方法体里面的,所以就重复了。这时候编译器会检查到重复变量。直接红色波浪线报错。

就算第二个a换一个变量类型,也是不允许的。

变量在同一个作用域里面要唯一,和变量类型没关系。

如上图,外面的a的作用域是黄色的,里面的a的作用域是绿色的。很明显外面的a的作用域是包括了里面的a的范围的。所以冲突了。

解决办法是里面的a换一个名字就可以。

再看一个例子

如果写成这样,还会冲突吗?

class Program
{
    static void Main()
    {
        int a = 10;

        {
            double b = 20;
        }

        {
            double b = 30;
        }

    }
}Code language: C# (cs)

答案是:不会,为什么,因为虽然有两个b变量。但是因为它们的作用域不重叠,所以不会报错。上面的b的作用域,是它所在的代码块,下面的b的作用域也是它所在的代码块,没有冲突,所以编译通过。看图

上面是两个b变量各自的作用域,用颜色表示了。所以现在读者们明白了吧。

Previous:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注