指標基礎概念
- 定義:
int *p; — * 是類型修飾符,宣告 p 為指向 int 的指標
- 取址:
&var — 獲取變數記憶體位址
- 解引用:
*p — 訪問指標指向的記憶體內容
- 空指標:
NULL (定義為 0),表示不指向任何有效對象
核心分類與代碼示例
1. 字串指標
char *str = "Hello World"; // 指向唯讀字串字面量
char *sub = str + 6; // 指向 "World"
// 注意:不可修改 str 指向的內容 (未定義行為)
2. 指標作為函數參數 (傳址調用)
void swap(int *a, int *b) {
int t = *a; *a = *b; *b = t;
}
int x=1, y=2; swap(&x, &y); // x=2, y=1
3. 陣列指標運算
int a[] = {11,22,33,44};
int *p = a; // p == &a[0]
*p; // 11
*(p+2); // 33
p+1; // 位址 + sizeof(int)
4. 二維陣列指標
int m[2][3] = {{0,1,2},{3,4,5}};
int (*p)[3] = m; // 關鍵:指向「含 3 個 int 陣列」的指標
p[1][2]; // 5
*(*(p+1)+2); // 等價展開
5. 函數指標
int max(int a, int b) { return a>b?a:b; }
int (*fp)(int,int) = max; // 宣告函數指標
fp(3,5); // 調用,返回 5
// 用途:回調、狀態機、插件架構、qsort 比較函數
6. 指標函數 (返回指標的函數)
const char* weekday(int n) {
static const char *names[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
return (n>=0 && n<=6) ? names[n] : "Invalid";
}
7. 指標陣列
char *names[] = {"Alice", "Bob", "Carol"}; // 3 個 char*
names[1]; // "Bob"
8. 多級指標
char *names[] = {"Alice", "Bob"};
char **pp = names; // 二級指標
pp++; // 指向 "Bob"
*pp; // "Bob"
9. void* 通用指標
void *raw = malloc(100); // 分配原始記憶體
int *pi = (int*)raw; // 必須強制轉型後使用
free(raw);
記憶體圖解關鍵點
- 指標本身佔 4 字節 (32 位) 或 8 字節 (64 位)
- 指標運算單位 = 所指類型大小:
int* + 1 增加 4 字節
- 二維陣列連續佈局,行指標跨度 =
列數 * sizeof(元素)
最佳實踐清單
- 初始化即賦值:
int *p = NULL; 或 int *p = &var;
- 解引用前檢查非空
- 釋放後置空:
free(p); p = NULL;
- 函數參數用
const 修飾只讀指標:void print(const int *p)
- 避免多級指標超過 2 級,改用結構體封裝