其他结构中变量的作用域 3个月前

上一节的一个要点不是只与函数之间的变量作用域有关:变量的作用域包含定义它们的代码块和直接嵌套在其中的代码块。这一点也适用于其他代码块,例如分支和循环结构的代码块。考虑下面的代码:

int i;
for (i = 0; i < 10; i++)
{
    string text = "Line" + Convert.ToString(i);
    Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);

字符串变量 textfor 循环的局部变量,这段代码不能编译,因为在该循环外部调用的 Console.WriteLine() 试图使用该变量 text,但是在循环外部该变量会超出作用域。修改代码,如下所示:

int i;
string text;
for (i = 0; i < 10; i++)
{
    text = "Line" + Convert.ToString(i);
    Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);  ❌

这段代码也会失败,原因是必须在使用变量前对其进行声明和初始化,但 text 只在 for 循环中初始化。由于没有在循环外进行初始化,赋给 text 的值在循环块退出时就丢失了。但可以进行如下修改:

int i;
string text = "";

for (i = 0; i < 10; i++)
{
    text = "Line" + Convert.ToString(i);
    Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);

这次 text 是在循环外部初始化,可以访问它的值。

在循环中最后赋给 text 的值可以在循环外部访问。可以看出,这个主题的内容需要花一点时间来掌握。在前面的示例中,循环之前赋给 text 空字符串,而在循环之后的代码中,该 text 就不会是空字符串了,其原因可能一下子看不出来。

这种情况的解释涉及分配给 text 变量的内存空间,实际上任何变量都是这样。只声明一个简单变量类型,并不会引起其他变化。只有在给变量赋值后,这个值才会被分配一块内存空间。如果这种分配内存空间的行为在循环中发生,该值实际上定义为一个局部值,在循环外部会超出其作用域。

即使变量本身未局部化到循环上,其包含的值却会局部化到循环上。但在循环外部赋值可以确保该值是主体代码的局部值,在循环内部它仍处于其作用域中。这意味着变量在退出主体代码块之前是没有超出作用域的,所以可在循环外部访问它的值。

幸好,C#编译器可检测变量的作用域的问题,根据它生成的错误信息修正程序有助于我们理解变量作用域问题。

最后一个要注意的一点是,应采用 “最佳实践方式”。一般情况下,最好在声明和初始化所有变量后,再在代码块中使用它们。一个例外是把循环变量声明为循环块的一部分,例如:

for (int i = 0; i < 10; i++)
{
    ...
}

其中 i 局部化于循环代码块中,但这是可以的,因为很少需要在外部代码中访问这个计数器。

image
EchoEcho官方
无论前方如何,请不要后悔与我相遇。
1377
发布数
439
关注者
2222787
累计阅读

热门教程文档

Objective-C
29小节
Javascript
24小节
Java
12小节
爬虫
6小节
Typescript
31小节