C語言存儲類修飾符和類型限定符

存儲類修飾符編程

聲明中出現的存儲類修飾符(storage class specifier)用於修改標識符的連接和對應對象的存儲週期(連接與存儲週期的概念將會在本章後面介紹)。連接(linkage)和存儲週期(storage duration)是C語言中常會遇到的困擾。連接(標識符的屬性)和存儲週期(對象的屬性)二者在聲明中都會受相同關鍵字集(存儲類修飾符)的影響。本章後面會介紹對象的存儲週期能夠是動態的、靜態的,或已分配的(allocated),而標識符的連接能夠是外部(external)、內部(internal)或不做限定的。相似「靜態連接」或「外部存儲」等說法在C語言中是沒有意義的。注意:對象有存儲週期,而非連接;標識符有連接,而非存儲週期。
一個聲明中不能出現多個存儲類修飾符。函數標識符只可使用存儲類修飾符extern或static。函數參數只可使用存儲類修飾符register。5種存儲類修飾符的含義以下:
auto
聲明中有修飾符auto的對象,具備動態存儲週期。這種修飾符只能用於函數內的對象聲明。在ANSI C中,默認狀況下函數內的對象聲明都有動態的存儲週期,因此不須要使用修飾符auto。
register
當聲明對象有動態存儲週期時,可使用修飾符register。該關鍵字告訴編譯器,所聲明對象的訪問應該儘可能快——理想狀況下,應該將該對象存儲在CPU寄存器(register)中。然而,編譯器可能並不會按照理想狀況那樣作,而是會把用register聲明的對象當成普通的動態存儲週期對象。無論怎樣,只要採用修飾符re-gister聲明瞭對象,就不能用地址運算符對該對象進行操做。
static
被聲明爲static的函數標識符具備內部連接,換句話說,別的翻譯單元沒法使用所聲明的函數標識符來訪問該函數。
被聲明爲static的對象標識符可能爲外部連接,也可能爲內部連接,至因而哪種連接形式,取決於對象的定義是在函數內仍是函數外。被聲明爲static的對象具備靜態存儲週期。所以,修飾符static容許定義局部對象(也就是具備語句塊做用域的對象)爲具備靜態的存儲週期。
extern
被聲明爲extern的函數和對象標識符具備外部連接。能夠在程序中任何地方使用這些標識符。外部對象具備靜態的存儲週期。
_Thread_local
修飾符_Thread_local聲明對象爲線程局部(thread-local),表示每一個線程都分別具備該對象的實例。只有對象能被聲明爲線程局部,而函數不能。若是在函數內部聲明一個線程局部對象,聲明必須具備修飾符extern或static。在一個表達式中,線程局部對象的標識符引用當前線程中對象的本地實例,當前線程指當前計算該表達式的線程。示例請參見14.4.1節。數組

類型限定符函數

能夠利用類型限定符修改聲明中的類型,類型限定符有const、volatile、restrict和_Atomic。聲明中可以使用多個類型限定符,它們的順序沒有限制。類型限定符列表內能夠屢次出現相同的類型限定符,或者經過限定typedef名稱的方式,反覆使用同一個限定符。編譯器會忽略重複出現的限定符,將它們視爲只出現一次。
各類類型限定符的含義以下:
const
對象的類型若是採用了限定符const,則該對象就是常量。在定義該對象以後,程序沒法修改它。
volatile
對象的類型若是採用了限定符volatile,則該對象能夠被其餘進程或事件修改。關鍵字volatile告訴編譯器在每次使用該對象值時,都要從新讀取它,即使程序自己自上一次獲取後再沒有修改過它的值。這種限定符一般用於硬件接口編程,以防止變量值被外部事件修改後,未能及時更新。
restrict
限定符restrict只適用於對象指針類型。這種類型限定符是C99新增長的,用來告訴編譯器,一個被指針所引用的對象,若是它能夠被修改,那麼只能被restrict限定的指針修改,不能被除該指針之外的其餘任何方式修改,不管是直接方式仍是間接方式。該特性容許編譯器採用特定優化技術,而該技術可能須要restrict特性的支撐。編譯器也有可能會忽略限定符restrict,而不對程序結果形成任何影響。
_Atomic
採用類型限定符_Atomic聲明的對象是一個原子對象(atomic object)。數組不能是原子對象。對原子對象的支持是可選的:C11實現版本中,若是定義了宏_STDC_NO_ATOMICS_,則表示程序不能聲明原子對象。關於原子對象的詳細介紹,請參見第14章。
編譯器也能夠將const對象存儲在內存中的只讀區域,可是volatile對象不能。若是程序不使用volatile對象的地址,也有可能編譯器乾脆不爲該對象分配內存。
對象若是同時使用了限定符const和volatile,以下例中ticks對象所示,它不能被程序自己修改,但能夠被其餘事件修改,例如時鐘芯片的中斷處理程序:
extern const volatile int ticks;優化

相關文章
相關標籤/搜索