修飾詞調整基本型別的表示範圍與語意;限定詞賦予額外語義約束(唯讀、易變、無別名)。
| 修飾詞 | 適用型別 | 效果 |
|---|---|---|
signed | 整數、字元 | 有號表示(預設) |
unsigned | 整數、字元 | 無號表示,範圍 0 ~ 2ⁿ-1 |
short | int | 縮短寬度(通常 16 位) |
long | int、double | 延長寬度(long int 常 32/64 位,long double 擴展精度) |
signed/unsigned 可作為 long/short 前綴:unsigned long int。int 可省略:unsigned short ≡ unsigned short int,long ≡ long int。char 是否預設 signed 由實作定義,跨平台請顯式指定 signed char/unsigned char。short int i; // 有號短整數
short unsigned int j; // 無號短整數
j = 50000;
i = j; // 位元模式相同,但解讀不同
cout << i << ' ' << j; // 輸出: -15536 50000
無號大數賦值給有號同寬型別會產生數值解讀錯誤,非溢位未定義行為,但邏輯錯誤極隱蔽。避免有號/無號混用比較與賦值,啟用編譯器警告 (-Wsign-conversion)。
| 限定符 | 語意 | 適用對象 |
|---|---|---|
const | 物件初始化後不可修改,編譯器強制檢查 | 變數、指標、參考、成員函數 |
volatile | 告知編譯器:值可能被程式不可見方式改變(硬體暫存器、訊號處理、多執行緒),禁止最佳化快取/重排 | 記憶體對應暫存器、共享旗標 |
restrict (C99) | 指標為唯一存取路徑,編譯器可激進最佳化(如向量化)。C++ 標準未納入,但編譯器常支援 __restrict/__restrict__ | 指標參數 |
const int *p1; // 指向 const int 的指標,不可透過 p1 修改值
int *const p2; // const 指標,不可改變指向,可修改值
const int *const p3; // const 指向 const int
int const *p4; // 同 p1,const 在型別左側
int *const p5; // 同 p2
口訣:讀從右向左。const 最近修飾誰就限制誰。
// 記憶體映射硬體暫存器
volatile uint32_t *STATUS_REG = (uint32_t*)0x40000000;
uint32_t status = *STATUS_REG; // 每次強制從記憶體讀取
// 訊號處理旗標
volatile sig_atomic_t flag = 0;
void handler(int) { flag = 1; }
while (!flag) { /* 等待 */ } // 不會被最佳化為無窮迴圈
⚠️ volatile 不提供執行緒同步,多執行緒共享資料請用 std::atomic/std::mutex。
void copy(int *__restrict dest, const int *__restrict src, size_t n) {
for (size_t i = 0; i < n; ++i) dest[i] = src[i];
}
// 編譯器假設 dest 與 src 不重疊,可產生向量化指令
const 是現代 C++ 核心,貫徹 const 正確性,讓介面語意清晰、編譯器協助檢查。volatile 僅用於硬體/訊號/編譯器不可見的外部修改,非執行緒同步工具。restrict 以編譯器擴充支援,極致效能優化時使用,需保證無別名。