2015-10-19 94 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