指標是一個**儲存記憶體位址**的變數。它指向某個型別的資料,透過解參考 (*) 存取該資料。指標本身佔用固定大小(32 位元系統 4 bytes,64 位元 8 bytes),與指向資料大小無關。
int i = 5; // 1. 一般變數
int* p = &i; // 2. 取址:p 儲存 i 的位址
int val = *p; // 3. 解參考:讀取 p 指向的值(5)
位址: 0x1000 0x1004 0x1008
+------+ +------+ +------+
| 5 | |0x1000| | ... | ← i (int), p (int*), 其他
+------+ +------+ +------+
i p
*p 透過 0x1000 找到 0x1000 處的 5
int i = 5;
int* p = &i;
std::cout << "i 的值: " << i << '\n'; // 5
std::cout << "*p 的值: " << *p << '\n'; // 5(同 i)
std::cout << "p 保存的位址: " << p << '\n'; // 0x7ffc...(i 的位址)
std::cout << "p 自身的位址: " << &p << '\n'; // 0x7ffc...(p 自己的位址,不同於 i)
關鍵區別:p(指標值=被指物件位址)vs &p(指標變數自身位址)。
int arr[5] = {10,20,30,40,50};
int* p = arr; // 陣列名退化為首元素指標
p[2] == *(p+2) == arr[2] == 30; // 等價
p += 2; // 移動 2 * sizeof(int) bytes,指向 arr[2]
p + n 移動 n * sizeof(T) 位元組p2 - p1 返回元素個數差(ptrdiff_t)int a = 10;
int* p1 = &a; // 一級指標
int** p2 = &p1; // 二級指標:指向指標的指標
int*** p3 = &p2; // 三級...
// 解參考層層剝洋蔥
**p2 == *p1 == a == 10;
int rows = 3, cols = 4;
int** matrix = new int*[rows]; // 1. 分配行指標陣列
for (int r = 0; r < rows; ++r)
matrix[r] = new int[cols]; // 2. 每行分配資料
// 使用 matrix[r][c]
// 釋放順序反轉
for (int r = 0; r < rows; ++r)
delete[] matrix[r];
delete[] matrix;
| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
int* p; *p = 10; | 野指標,指向隨機位址 | 初始化:int* p = nullptr; 或 new int |
delete p; *p = 5; | 懸空指標,記憶體已釋放 | 刪除後 p = nullptr; |
int* p = new int[10]; delete p; | 陣列 new 需配對 delete[] | delete[] p; |
void f(int* p) { p = new int; } | 函數內修改指標不影響外部 | 傳 int*& 或 int** |
return &localVar; | 返回區域變數位址 | 返回動態記憶體、static、或值傳回 |
std::unique_ptr(獨佔)、std::shared_ptr(共享)、std::weak_ptr(打破循環引用)T*, size_t指標是 C++ 掌控記憶體的核心工具。理解 位址、解參考、算術、多級間接、所有權 五大維度,配合現代智慧指標與容器,即可寫出高效、安全、無洩漏的系統級代碼。