1. 程式人生 > >深入c語言_作用域

深入c語言_作用域

我們知道,C語言中變數的作用域有4種,我們不去討論函式作用域,因為涉及到goto語句。剩下的三種作用域,程式碼塊作用域,檔案作用域,原型作用域。

程式碼塊作用域:位於一堆花括號之間的所有語句是程式碼塊,在程式碼塊的開始位置宣告的識別符號的作用域就是程式碼塊作用域。從宣告開始,到所處的最小的右大畫括號結束。

檔案作用域:任何在程式碼塊之外宣告的識別符號的作用域是檔案作用域。從宣告開始,到檔案結尾結束。

原型作用域:在函式原型中宣告的識別符號的作用域是原型作用域。從宣告開始,到有小括號結束。(只是函式原型宣告時,定義時的形參屬於程式碼塊作用域)

識別符號在宣告時就決定了自己的作用域,作用域的告訴了我們變數允許你在哪些範圍內使用。

我們先看一個例子

上面圖片中的變數都是什麼作用域我們不在分析,都可以看出來,不會的對照上面的方法。這個例子很簡單,只是單純的為了演示寫的,下面我給出此程式碼的反彙編。

程式碼有什麼疑問分析反彙編絕對可以解決。壓棧出棧的細節我就不分析了,對應的反彙編也跳過,從movw $0x11,-0x4(%ebp)開始分析。這個變數的只是0x11,我們對應上面的c檔案知道這個是變數blck,是程式碼塊作用域,屬於同一個型別的作用域還有下一條反彙編對應的變數block_scope,可以看除反彙編都是通過棧去定址的,那麼主函式沒有結束,棧就不一直是當前的模樣,記憶體是一直存在的,值也不會消失,但是當block_scope出了作用域時編譯器不允許我們使用了,我們知道記憶體還是在的,也可以定址得到,所以我們得出的結論是編譯器做了手腳,不允許我們在通過變數名去訪問那塊記憶體了,換句話說就是變數對應的記憶體和值都在,只是編譯器不能通過變數名定址得到了。那句含有0x33的反彙編指令對應的變數就是file_scope,有檔案作用域,我們發現它的定址是一個常量地址,說明在編譯期間,編譯器直接給用一個地址去替代這個變數名,地址肯定是一直可以訪問的,所以他一直可以訪問,知道離開這個檔案時,編譯器又做了手腳。