通過型別限定符可以修改宣告中的型別,
型別限定符有 const、volatile、restrict 和 _Atomic。宣告中可使用多個型別限定符,它們的順序沒有限制。
型別限定符列表內可以多次出現相同的型別限定符,或者通過限定 typedef 名稱的方式,反復使用同一個限定符。編譯器會忽略重複出現的限定符,將它們視為只出現一次。
各種型別限定符的含義如下:
(1) const
物件的型別如果採用了限定符 const,則該物件就是常數。在定義該物件之後,程式無法修改它。
(2) volatile
物件的型別如果採用了限定符 volatile,則該物件可以被其他進程或事件修改。關鍵字 volatile 告訴編譯器在每次使用該物件值時,都要重新讀取它,即便程式本身自上一次獲取後再沒有修改過它的值。這種限定符通常用於硬體介面程式設計,以防止變數值被外部事件修改後,未能及時更新。
(3) restrict
限定符 restrict 只適用於物件指標型別。這種型別限定符是 C99 新增加的,用來告訴編譯器,一個被指標所參照的物件,如果它可以被修改,那麼只能被 restrict 限定的指標修改,不能被除該指標以外的其他任何方式修改,無論是直接方式還是間接方式。該特性允許編譯器採用特定優化技術,而該技術可能需要 restrict 特性的支撐。編譯器也有可能會忽略限定符 restrict,而不對程式結果造成任何影響。
(4) _Atomic
採用型別限定符 _Atomic 宣告的物件是一個原子物件(atomic object)。陣列不能是原子物件。對原子物件的支援是可選的:C11 實現版本中,如果定義了宏 _STDC_NO_ATOMICS_,則表示程式不能宣告原子物件。
編譯器也可以將 const 物件儲存在記憶體中的唯讀區域,但是 volatile 物件不能。如果程式不使用 volatile 物件的地址,也有可能編譯器乾脆不為該物件分配記憶體。
物件如果同時使用了限定符 const 和 volatile,如下例中 ticks 物件所示,它不能被程式本身修改,但可以被其他事件修改,例如時鐘晶片的中斷處理程式:
extern const volatile int ticks;
下面是使用型別限定符宣告的更多範例:
const int limit = 10000; // 一個int常數物件
typedef struct { double x, y, r; } Circle; // 一個結構型別
const Circle unit_circle = { 0, 0, 1 }; // 一個Circle常數物件
const float v[] = { 1.0F, 0.5F, 0.25F }; // 一個具有float常數元素的陣列
volatile short * restrict vsPtr; // 一個限定指標,指向volatile short
對指標型別來說,在星號右邊的型別限定符,其限定的是指標本身,而在星號左邊的型別限定符,其限定的是指標所指向的物件型別。在最後一個範例中,指標 vsPtr 使用限定符 restrict,該指標所指向的物件使用限定符 volatile。