下面是代码:
#include <stdio.h>
int var0 = 5;
int main() {
int var1 = 7;
int var2 = 9;
printf("a) %d, %d, %d\n", var0, var1, var2);
{
int var1 = 17;
printf("b) %d, %d, %d\n", var0, var1, var2);
var0 = 15;
var2 = 19;
printf("c) %d, %d, %d\n", var0, var1, var2);
{
int var0 = 25;
printf("d) %d, %d, %d\n", var0, var1, var2);
}
}
printf("e) %d, %d, %d\n", var0, var1, var2);
}
编译器的结果是:
a) 5, 7, 9
b) 5, 17, 9
c) 15, 17, 19
d) 25, 17, 19
e) 15, 7, 19
我不理解e,如果我没弄错的话,外块对内块有影响,但是反过来就不是这样了,所以在e的情况下,只有5,7和9在外块,因此在作用域中,编译器给我的var0,15在内块,因此不在作用域中,var2也是这样,你能解释一下我的误解吗
3条答案
按热度按时间ax6ht2ek1#
我不明白。
在
var0 = 15;
处,var0
的唯一可见声明是在任何函数外部声明的int var0 = 5;
,因此var0 = 15;
中的var0
引用初始的var0
,并且赋值将其设置为15。后面的
int var0 = 25;
声明了一个新的var0
,它隐藏了前面的var0
,因此用25进行初始化不会改变前面的var0
,而是将其保留为15。int var1 = 17;
声明了一个新的var1
,它隐藏了先前的var1
,因此使用17进行初始化不会改变先前的var1
,而是将其保留为7。在
var2 = 19;
,var2
的唯一可见声明是在main
中声明的int var2 = 9;
,因此var2 = 19;
中的var2
引用前面的var2
,并且赋值将其设置为19。jvlzgdj92#
程序的变量位于以下4个scopes中:
1.文件作用域(即全局作用域)
1.外部块作用域(整个函数
main
的作用域)1.中块示波器
1.最内层块作用域
程序定义以下变量:
1.文件范围中的
var0
,初始化为值5
var0
在最里面的块范围内,初始化为值25
1.外部块范围中的
var1
,初始化为值7
var1
位于中间块范围内,初始化为值17
var2
,初始化为值9
所有这五个变量都是不同的,即使它们具有相同的名称。
在程序的后面,将变量#1的值更改为
15
,将变量#5的值更改为19
。更改变量#1的值不会影响变量#2(将来)的值,因为如前所述,变量#1和#2是不同的,尽管它们具有相同的名称。这条线
将使用值
15
覆盖现有变量var0
的值,而行将定义一个新变量
var0
,它"隐藏"了现有变量var0
的名称,因此在该作用域及其嵌套子作用域中对名称var0
的所有引用都指向新变量。这使得旧变量var0
在这些作用域中不再直接可访问。(不过,旧变量在这些作用域中仍然可以通过指针间接访问。)这条线
将打印变量#1、#3和#5。
如前所述,变量#1初始化为值
5
,但后来更改为值15
。由于此更改发生在执行printf
行之前,因此printf
行将为变量#1的值打印15
。如前所述,变量#3被初始化为值
7
,之后不会更改,因此,printf
行将为变量#3的值打印7
。如前所述,变量#5初始化为值
9
,但后来更改为值19
。由于此更改发生在执行printf
行之前,因此printf
行将为变量#5的值打印19
。因此,引用的
printf
行将打印以下内容:如果我没记错的话,外块对内块有影响,但反过来就不是这样了。
这个陈述是不正确的。它正好相反。但是,正如前面提到的,由于内部作用域的变量名隐藏了外部作用域的变量名,所以这种影响是有限的。
执行外部作用域时内部嵌套作用域do not exist的变量。无法访问尚不存在或生存期已结束的变量。
旁注:如果变量名隐藏其他变量名的行为是不可取的,那么您可能需要考虑配置您的编译器,以便在发生此类隐藏时发出警告。例如,在gcc和clang上,您可以使用
-Wshadow
命令行选项。ujv3wf0j3#
如果我没记错的话,外块对内块有影响,但反过来就不是这样了。
你错了。没有这样的规则。影响力是双向的。
所以在e的例子中,只有5,7和9在外部块,因此在作用域中,编译器给我的是15,它在内部块,因此不在作用域中,对于var2也一样。
块对访问不重要,它们对“作用域”很重要。作用域,就像狙击手作用域一样,定义了你能看到哪些变量。当你能看到它们时,你就能改变它们。
当你在作用域中定义另一个var1时,它会遮蔽外面的那个,所以
var1
在外面的作用域意味着“外面的var1”,而var1
在里面的作用域意味着“里面的var1”,你可以看到外面的var1,因为里面的var1挡住了你的路。这称为“variable shadowing“。
要理解这一点,请重命名变量以消除名称冲突:
内部变量不存在于外部作用域中,但外部变量存在于内部作用域中。