const 與指針結合時,關鍵在於 const 相對於 * 的位置:
| 聲明形式 | 指針本身 | 指向的數據 | 典型用途 |
|---|---|---|---|
int const *pconst int *p | 可修改 | 不可修改 | 函數參數傳遞只讀緩衝區 |
int * const p | 不可修改 | 可修改 | 固定指向特定硬體寄存器或內存映射區 |
const int * const p | 不可修改 | 不可修改 | 只讀查找表、常量字符串指針 |
在 GCC 下,const 修飾的變量僅是編譯器層面的只讀承諾,若通過強制類型轉換獲取非 const 指針,仍可修改內存值:
int main(void) {
const int a = 5;
// a = 6; // 編譯報錯:assignment of read-only variable 'a'
int *p = (int *)&a; // 強制轉換消除警告
*p = 6;
printf("a = %d.\n", a); // 輸出 a = 6,證明內存被修改
return 0;
}
原理:const int a 僅告訴編譯器「不應修改」,並未將內存頁標記為硬件只讀(除非鏈接器將其放入 .rodata 段且啟用寫保護)。嵌入式開發中若需真正只讀,須配合 const + 鏈接腳本放入只讀段,或使用硬體存儲保護單元(MPU)。
const int *p 表達「只讀數據」語義,增強代碼可讀性與編譯器優化機會。int * const p。const 變量通過指針修改,屬於未定義行為,可能導致優化錯誤或運行時崩潰。