[c]
void fun(char *pa) {
pa = "bb"; // 只修改了形參 pa 的副本
}
int main() {
char *p = NULL;
fun(p);
// p 仍為 NULL,未被修改
}
原因:參數傳遞本質是**值拷貝**。pa = p 拷貝的是地址值。函數內修改 pa 只影響副本,不影響實參 p。
[c]
void fun(char **pa) {
*pa = "bb"; // 解引用一次,修改實參指向的內存
}
int main() {
char *p = NULL;
fun(&p); // 傳遞 p 的地址
// p 現在指向 "bb"
}
main 棧幀: fun 棧幀:
p (0x7ffe...) ───► pa (0x7ffe...) ──► 同一地址 0x7ffe...
*pa = "bb" 修改 0x7ffe... 處的值
實參 p 的地址 &p 被拷貝給形參 pa。*pa 解引用定位到 p 所在的棧槽,直接修改其存儲的地址值。
[c]
char *p = "aa"; // 指向只讀區
*pa = "bb"; // 修改指向,合法(指向另一個只讀字面量)
// 但若嘗試修改內容:
// *pa = "bb"; // 只是改指向,OK
// strcpy(*pa, "cc"); // 崩潰!字面量在只讀段,不可寫
正確做法:若需修改字符串內容,實參必須指向可寫內存(棧數組或堆內存):
[c]
char buf[100] = "aa";
char *p = buf;
fun(&p); // 此時 *pa 可安全 strcpy
**:修改一級指針的指向(如分配內存並返回指針)。***:修改二級指針的指向(如動態分配指針數組)。| 需求 | 參數類型 | 調用方式 | 函數內操作 |
|---|---|---|---|
| 修改指向的值 | int *p | fun(ptr) | *p = val |
| 修改指針指向 | int **p | fun(&ptr) | *p = new_addr |
| 修改指針數組 | int ***p | fun(&arr) | *p = new_arr |
掌握「傳地址以修改原變量」這一核心原理,指針層級不再是迷題。