在深入探討「指向指標的指標」之前,我們先快速回顧一下指標的核心概念。指標本質上是一個變數,其值為另一個變數的記憶體位址。透過指標,我們可以間接存取或修改目標變數的值。
假設我們宣告如下變數:
short int i;
char a;
short int *pi;
編譯器會在記憶體中為它們分配空間。若執行 i = 50; pi = &i;,則 pi 存放的值即為 i 的起始位址。此時 *pi 與 i 完全等價,對 *pi 的讀寫即是對 i 的讀寫。
指標變數本身也佔用記憶體空間,因此它也有自己的位址。我們可以宣告另一個指標來儲存這個位址,這就是指向指標的指標,俗稱雙重指標或二級指標。
short int **ppi; // 宣告一個指向 short int* 的指標
ppi = π // 將 pi 的位址指派給 ppi
記憶體模型如下:
ppi 的值 = pi 的位址 (例如 10)*ppi 的值 = pi 的值 = i 的位址 (例如 6)**ppi 的值 = *pi 的值 = i 的值 (50)透過解引用層層遞進,雙重指標終極指向了原始資料。
這是雙重指標最經典的用途。在 C 語言中,函式參數傳遞屬於「值傳遞」。若在函式內修改指標參數指向的位址,無法影響呼叫端的原始指標。
void find1(char array[], char search, char *pa) {
// ... 查找邏輯 ...
pa = array + i; // 僅修改區域副本 pa,外部 p 不受影響
}
void find2(char array[], char search, char **ppa) {
// ... 查找邏輯 ...
*ppa = array + i; // 透過解引用修改外部指標 p 的值
}
// 呼叫端
char *p = 0;
find2(str, a, &p); // 傳入 p 的位址
此時 ppa 指向 p,*ppa 即代表 p 本身。在函式內對 *ppa 賦值,實際上就是在修改主程式中的 p,從而實現「輸出參數」的效果。
指向指標的指標(**)是 C 語言實現指標參數「引用傳遞」語意的關鍵機制。它允許函式修改呼叫端指標變數本身的指向,廣泛應用於動態記憶體分配、鏈結串列節點操作、字串處理等核心場景。掌握「ppi -> *ppi -> **ppi」的三層關係,是進階 C 程式設計的必修課。