2015-10-19 77 views
0

我正在学习一门课程,我们在系统级编程方面做了很多工作,现在我们已经开始对C语言进行介绍了。我们给出了一些代码,并告诉我们以陈述每个'printf'语句打印的值。我知道如何使用Java和Python等语言进行常规打印语句。但是给出的代码具有我以前从未见过的印刷部分的实体。这些语句的顺序的执行,B,C,D。下面是代码:在printf中使用语句体C

int t; /* This variable is global */ 

{ 
    int t = 2; 

    printf("%d\n", t);  /* A */ 
    { 
     printf("%d\n", t); /* B */ 
     t = 3; 
    } 
    printf("%d\n", t);  /* C */ 
} 

{ 
    printf("%d\n", t);  /* D */ 
} 

,混淆我的是一些打印语句有机构的一部分。打印声明内的打印声明?

所以这是我在想什么:t = 2所以当我们到达A时,它首先在A内执行主体。因此,该体中的第一条语句是打印此时为2的t。然后,在打印2之后,我们将t中的值更改为3.之后,我们转到C打印t,它是3(我猜?我不确定)。之后,我们转到包含D的主体。Int t是上面声明的全局变量,但它不会被初始化(除了代码的第一部分)。因此,在包含D的第二部分中,由于t未在该代码块中初始化,是否会出现错误?

2 
3 
3 
Error 

我觉得我错了。

+6

他们没有尸体。大括号('{}')只是创建新的范围,并且与'printf'语句无关。 –

+0

@OliverCharlesworth - 好的,谢谢。所以它会打印:2,3,2,错误?第三个值是否为2,因为t在大括号范围内变为3?另外,说D是一个错误还是仅仅打印垃圾值是否正确? – GenericUser01

+1

发生这种情况是因为在第一次呼叫中't = 2',接下来两次't = 3',最后一次呼叫最后't未初始化'。 (例如,从来没有为外部作用域't'设置值 - 它只是在该范围内声明为'int t') –

回答

2

首先,你有一个全局变量t,它被初始化为0(据我所知,如果没有明确地初始化,在C中的所有全局变量初始化为0)

然后,块被打开和局部变量t被声明并初始化为2,这会影响整个块的全局变量(在java中这是一个错误,编译器会抱怨并拒绝使用相同的名称)。

第一printf,这是块内,印刷品2

然后嵌套块打开,在它一个printf。这个printf还将使用本地变量t,再次打印2。

然后t被赋值3.这个"t"不能是局部变量以外的其他值。

然后,嵌套块关闭,我们又回到了第一个仍然打开的块,其中声明了本地t。此处的printf打印3.

然后第一个块完成,因此局部变量t消失。一个新块打开,最后一个printf打印全局变量t的值,这是该块中唯一已知的变量。它打印0.

1

花括号开始和结束新的作用域,就像他们对函数做的一样。

程序中有两个“主要块”。一个包含变量t的定义,因此影响全球t。因此打印出2,23。第二个块可以访问全局t,因此第二个块中的printf将输出全局的t的值。

默认情况下,全局变量初始化为0,所以最后的printf调用将0打印到屏幕。
局部变量没有用任何值初始化,所以最后的printf调用会产生未定义的行为。

输出是

2 
2 
3 

,之后

0 

如果 “全球” t真的全球(可能)一些随机值,如果它是本地。发生


未定义的行为。任何事情都可能发生。在这种情况下,它可能是打印出来的随机值。

+0

对printf()的所有调用都将打印已知值,所以这个答案是正确的,直到下面这句话:“如果”全球t真的是全球性的......“从此以后的一切都是不正确的。对我来说显而易见的是,真正的项目正在测试/演示代码片段是作用域规则 – user3629249

+0

@ user3629249请问你能解释一下你的最后一句话吗?你认为什么是不正确的? – Downvoter

+0

代码片段正在测试OP关于变量范围的知识,而不是关于他们对printf()函数这个目标(了解变量的范围)清楚地表明了每次调用printf()时要打印的内容的要求,OP的发布代码清楚地表明了第一个't '变量是全局性的,所以它必须在文件全局区域中,所以它被初始化为0.所以不用担心第一个't'变量在全局范围内。所以它不是'undefined behaviour' – user3629249