close
沃洛夫文翻譯(全域變數)
只履行一次翻譯社 main() 履行前由 "可載入履行檔 ELF" (或二進位影象 binary image) 拷貝至准確之 .data 區段位址內
- 一共有 4 個 Storage Classes:
- 主動變數: automatic
- 外部變數: external
- 靜態變數: static
- 暫存器變數: register
- C 的變數大致分為二類: 外部變數 (external, 也可以稱為全域變數) 及主動變數 (automatic翻譯社 或者是區域變數). 二者區分是以變數定義出現在 .c 檔中的位置來區分: 由於 C 語言限制了函數區塊中不行以再定義函數, (C++ 也不支援, 這點和 Javascript 是分歧的), 所以函數區塊內的就是主動變數翻譯社 函數區塊外的就是外部變數. 這二種變數界說時都不需加 keyword 修飾 (實際上, 外部變數沒有潤色字; 自動變數的修飾字是 auto, 但一般都省略)
- 外部變數紛歧定要呈現在 .c 檔中的最前面, 可以安插在二個函數區塊的中間翻譯社 受影響的是該變數的 scope: 變數出現之前的函數沒法利用該變數
- 靜態變數是外部變數或自動變數在定義時多加上 keyword static, 首要改變二件事: 改變變數利用的記憶體區段, 及縮小可視局限 (scope) 附帶一提: static 也能夠加在函數定義的前面, 也是示意這個函數是內部函數, 可視範圍縮小到只在檔案內, 並且沒法被外部檔案設 extern 來參考.
- Keyword register 則是要求改用 CPU 內部的暫存器來存放變數值, 而大部份 CPU 內部的暫存器都不多並且數目也分歧, 所以只能加在自動變數前面. 而且不包管告竣, 沒法達成時就降級釀成主動變數.
- 函數的參數則是一種特化的主動變數, 通常爲預設利用 register 變數, 但是會依據 CPU 種類分歧而有些轉變. 例如:
- ARM CPU 的官方規範是函數的前 4 個參數會使用 r0~r3 來實作, 跨越 4 個參數的部份則利用 stack.
- 但 intel x86 CPU 則
只有利用 register A. 其他無法使用利用 register 變數的參數都要利用 stack6 (參考 Wiki X86 calling conventions) - Keil C51 則預設不用 stack, 改用主動變數翻譯社 詳細請參考這一篇C 說話:Keil C51 和標準 C 說話的差異
- 另外 C 還有二個變數的限制詞 (qualifier)翻譯社 const 和 volatile
- const 是限制該變數不克不及被點竄 (目前大部份 C 編譯器 (例如:gcc翻譯社 ARM/MDK) 會利用 .text6 區段, 這個區段可以在 link 時指定到 ROM/Flash 記憶體上. 可是 Keil C51 不會, Keil C51 要用 const code 才會是用 ROM, 只用 const 照樣會佔用 DATA RAM)
- volatile 是限定不成以被快取到 CPU 內部的暫存器翻譯社 必須每次存取都真實的讀/寫該變數所佔用的位址 (意即:指定該變數的存取動作不作最好化). 它經常出現在界說週邊晶片的暫存器, 特別是週邊晶片的輸入暫存器部份必然要加 volatile 否則編譯出來的履行碼無法准確反應週邊晶片的現況. 還有多工情況中作為 semaphore 的變數也會要加上 volatile 這個 keyword.
- 與同一區塊內的變數同名時, 編譯毛病.
- 與區塊外層變數同名時, 外層變數被遮蔽.
life-time
申明:
備註:
每次進入函數或區塊後立即執行C 說話的變數有所謂的 storage class翻譯社 初學時對傍邊的差別並不是很容易弄清晰, 後來華頓翻譯公司把各種條件稍作收拾整頓, 於是有了下面的表格:
文章標籤
C
C 說話
變數
static
external
Keil C51
.text
.bss
.data
c variable scope
c varibale lifetime
const
volatile
- 界說會保留記憶體, 宣告則不會. 對變數來講除 extern 是宣佈之外, 其他的都是定義.
- 可視規模: 是指在程式的那一個段落可使用該變數. 主動變數 (使用 stack 堆疊區) 在分開界說他的 {} 區塊後就有可能被他人佔用翻譯社 所以可視規模同生命期. 外部變數一脫離定義的檔案就不可視, 但可使用 extern 宣佈來從新取得. (現實上翻譯社 幫我們完成這件事的是 linker). 但靜態變數則限制不行以被 extern 的宣告取得可視性. (compiler 的語法查抄禁止了我們獲得其可視性)
- 生命期: 是指變數佔用記憶體的時候翻譯社 只有自動變數 (利用 stack 堆疊區) 可以重覆利用記憶體空間, 其他都是永久佔據 (embebbed system) 或載入執行時佔用.
- 指未利用 va_arg (改觀個數參數)的情形. 若使用 va_arg, 需運用一些技能查抄參數個數, 不然會發生利用毛病的參數, 或引發程式當掉.
- 初值設定指的在界說變數時, 跟從在其後的等號 (=) 及厥後的運算式
- .text, .bss翻譯社 .data 是一般編譯器之預設記憶體區段名稱翻譯社 linker (或者是 loader) 會放置現實的記憶體位址給各個區段.
- .text 為唯讀區段, 放置程式及常數資料 (小型 embedded system 會將之安裝於 ROM/Flash 中)
- .data 為可讀寫區段, 放置初值不為 0 的變數 (使用 ROM/Flash 時會先附在 .text 以後). 在 main() 入手下手執行前, 由 "可載入執行檔 ELF" (或二進位影象 binary image) 拷貝至准確之 .data 區段位址內, 是故外部變數或靜態變數的初始值只能用常數運算式
- .bss 為可讀寫區段翻譯社 放置初值為 0 的變數. 在 main() 入手下手執行前翻譯社 .bss 區段會被清為 0
- stack 為堆疊區 (大陸用語: 棧) 一般是呼喚函數時的功課區 (返回位址暫存, 傳遞參數, 區域變數和返回值之貯存區), heap 為堆積區 (大陸用語: 堆) 是呼喚 malloc() 時獲得記憶區塊的來源.
條件/狀態 | 外部變數 scope | 自定義位置 (沒必要需在檔案的最前面) 至檔案結束 | 函數內 (或者 {} 區塊內) | 函數內 | |||
---|---|---|---|---|---|---|---|
生命期3 呼喚前履行設定 | |||||||
預設利用之記憶體區段 | 無初值 | .bss6 | stack6 | register 或 stack6 | |||
有初值 | .data6 | stack6 | register 或 stack6 |
本文來自: http://magicjackting.pixnet.net/blog/post/71949519-c-%E8%AA%9E%E8%A8%80%3A%E9%97%9C%E6%96%BC%E8%AE%8有關各國語文翻譯公證的問題歡迎諮詢華頓翻譯公司02-77260932
文章標籤
全站熱搜