首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 常量指針與指針常量:const 位置決定語義的核心規則

     編輯:關於C++

核心口訣:const 修飾誰,誰就不可變

const 出現在 * 左邊 → 修飾指向的值(常量指針/指向常量的指針)
const 出現在 * 右邊 → 修飾指針本身(指針常量)

1. 指向常量的指針

const int* p1;    // 或 int const* p1
int const* p2;    // 等價寫法
  • 值不可變:*p1 = 10; // ❌ 編譯錯誤
  • 指針可變:p1 = &other; // ✅ 合法
  • 可指向非常量對象(隱式加 const)或常量對象

代碼示例

int a = 10, b = 20;
const int* p = &a;  // p 指向 a
// *p = 30;        // ❌ 錯誤:不能通過 p 修改值
p = &b;             // ✅ 合法:p 可指向別處
cout << *p;         // 輸出 20

const int c = 100;
const int* q = &c;  // ✅ 合法:常量指針指向常量
// int* r = &c;    // ❌ 錯誤:非常量指針不能指向常量(丟棄 const)

2. 指針常量

int* const p3;    // 必須初始化
  • 指針不可變:p3 = &other; // ❌ 編譯錯誤
  • 值可變:*p3 = 10; // ✅ 合法
  • 聲明時必須初始化,且不可再指向其他地址

代碼示例

int a = 10, b = 20;
int* const p = &a;  // 必須初始化
*p = 30;            // ✅ 合法:修改 a 為 30
// p = &b;         // ❌ 錯誤:p 是常量指針,不能改變指向
cout << a;          // 輸出 30

3. 指向常量的指針常量(雙重 const)

const int* const p4 = &a;  // 或 int const* const p4
// *p4 = 10;  // ❌ 值不可變
// p4 = &b;   // ❌ 指針不可變
// 完全只讀,類似引用但可為空

快速判斷表

聲明值可改?指針可改?俗稱
int* p✅✅普通指針
const int* p / int const* p❌✅常量指針 / 指向常量的指針
int* const p✅❌指針常量
const int* const p❌❌常量指針常量

實戰場景

函數參數:防止誤修改

void printArray(const int* arr, size_t n) {
    // 保證不修改 arr 指向的數據
    for (size_t i = 0; i < n; ++i) cout << arr[i] << ' ';
}

迭代器設計

// 只讀迭代器
using const_iterator = const T*;
// 可寫迭代器
using iterator = T*;

嵌入式寄存器映射

volatile uint32_t* const UART_DR = (uint32_t*)0x40004000;
// 地址固定(指針常量),值可讀寫但編譯器不優化(volatile)

C++11 新增:nullptr 與 const

const int* p = nullptr;  // 類型安全的空指針
int* const q = nullptr;  // 指針常量初始化為空
// 建議統一使用 nullptr 替代 NULL/0

記憶口訣(從右向左讀)

「const 修飾左邊的東西;若左邊沒東西,修飾右邊」

  • const int* p → const 修飾 int → 指向 const int 的指針
  • int* const p → const 修飾 * → const 指針
  • const int* const p → 兩個 const 分別修飾 int 和 *

掌握這一規則,再複雜的聲明(如函數指針、多重指針)也能秒懂。建議配合 cdecl 工具練習:cdecl> explain const int* const* p。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved