C 語言中的指向指針的指針(雙重指針)
你好,有抱負的程序员!今天,我們將進入指針的世界——特別是指向指針的指針。我知道你可能在想什麼:“指針?雙重指針?這聽起來像個夢魘!”但別擔心,我保證會讓這個主題變得有趣且容易理解。所以,拿起你最喜歡的飲料,放鬆一下,我們一起深入探討吧!
C 語言中的雙重指針是什麼?
想象一下你正在參加尋寶遊戲。你有一張地圖(我們稱之為指針),它引導你到達一個寶箱。但驚喜!在寶箱裡,還有另一張地圖(另一個指針),它會引導你到達真正的寶藏。這基本上就是雙重指針的概念——一個指向另一個指針的指針。
在 C 語言編程中,雙重指針正如其名——一個指向指針的指針。它是一個變量,用於存儲另一個指針的地址。這聽起來可能一開始會有些混亂,但別擔心,我們會一步一步來解析。
指向指針的指針的聲明
我們先從如何聲明雙重指針開始。語法非常直接:
int **ptr;
在這裡,ptr
是一個指向指針的指針,該指針指向一個整數。第一個星號 *
讓它成為一個指針,第二個 *
讓它成為一個指向指針的指針。
指向指針(雙重指針)的示例
我們來看一個簡單的例子來更好地理解這一點:
#include <stdio.h>
int main() {
int x = 5;
int *p = &x;
int **pp = &p;
printf("x 的值:%d\n", x);
printf("使用 p 顯示 x 的值:%d\n", *p);
printf("使用 pp 顯示 x 的值:%d\n", **pp);
return 0;
}
輸出:
x 的值:5
使用 p 顯示 x 的值:5
使用 pp 顯示 x 的值:5
讓我們來解析一下:
- 我們聲明了一個整數
x
並將其初始化為 5。 - 我們創建了一個指針
p
,它指向x
。 - 我們創建了一個雙重指針
pp
,它指向p
。 - 然後我們以三種不同的方式列印出
x
的值:
- 直接使用
x
- 使用單一指針
p
(我們用*p
進行一次解引用) - 使用雙重指針
pp
(我們用**pp
進行兩次解引用)
這三種方法都會得到相同的值:5。這就像使用不同的地圖找到寶藏一樣!
C 語言中的普通指針是如何工作的?
在我們進一步探討雙重指針之前,先快速複習一下普通指針是如何工作的:
int y = 10;
int *q = &y;
printf("y 的值:%d\n", y);
printf("y 的地址:%p\n", (void*)&y);
printf("q 的值:%p\n", (void*)q);
printf("q 指向的值:%d\n", *q);
輸出:
y 的值:10
y 的地址:0x7ffd5e8e9f44
q 的值:0x7ffd5e8e9f44
q 指向的值:10
在這裡,q
是一個存儲 y
地址的指針。當我們使用 *q
時,我們正在訪問存儲在該地址的值。
雙重指針是如何工作的?
現在我們將這個概念延伸到雙重指針:
int z = 15;
int *r = &z;
int **rr = &r;
printf("z 的值:%d\n", z);
printf("z 的地址:%p\n", (void*)&z);
printf("r 的值:%p\n", (void*)r);
printf("r 的地址:%p\n", (void*)&r);
printf("rr 的值:%p\n", (void*)rr);
printf("r 指向的值:%d\n", *r);
printf("rr 指向的值:%p\n", (void*)*rr);
printf("rr 指向的指針的值:%d\n", **rr);
輸出:
z 的值:15
z 的地址:0x7ffd5e8e9f48
r 的值:0x7ffd5e8e9f48
r 的地址:0x7ffd5e8e9f50
rr 的值:0x7ffd5e8e9f50
r 指向的值:15
rr 指向的值:0x7ffd5e8e9f48
rr 指向的指針的值:15
這可能看起來有點複雜,但讓我們來解析一下:
-
z
是一個值為 15 的整數。 -
r
是一個存儲z
地址的指針。 -
rr
是一個存儲r
地址的雙重指針。 -
*r
給我們z
的值(15)。 -
*rr
給我們r
的值(即z
的地址)。 -
**rr
給我們z
的值(15)。
這就像這樣:rr
指向 r
,r
指向 z
。所以 **rr
就像在說“跟隨第一個指針,然後跟隨第二個指針,並給我那裡的值”。
雙重指針行為與普通指針一樣
這裡有一個小秘密:雙重指針只是一個指針,但它指向的是另一個指針,而不是整數或浮點數。這意味著我們可以對雙重指針進行所有與普通指針相同的操作。
例如,我們可以在數組中使用雙重指針:
int main() {
char *fruits[] = {"Apple", "Banana", "Cherry"};
char **ptr = fruits;
for(int i = 0; i < 3; i++) {
printf("%s\n", *ptr);
ptr++;
}
return 0;
}
輸出:
Apple
Banana
Cherry
在這個例子中,fruits
是一個指向字符串的指針數組,而 ptr
是一個指向字符指針的指針(可以指向 fruits
的元素)。
C 語言中的多級指針(三重指針可能嗎?)
是的,你可以有三重指針、四重指針等等!理論上,指針的間接層次沒有限制。然而,在實際應用中,很少會看到超過雙重指針的情況。
這裡有三重指針的例子:
int x = 5;
int *p = &x;
int **pp = &p;
int ***ppp = &pp;
printf("x 的值:%d\n", ***ppp);
輸出:
x 的值:5
但記住,只是因為你可以這樣做,並不代表你應該這樣做。多個間接層次會使代碼更難以閱讀和維護。正如古老的編程諺語所說:“計算機科學中的所有問題都可以通過另一個間接層次來解決……除了間接層次太多的問題!”
結論
恭喜你!你剛剛順利穿越了 C 語言中複雜的雙重指針水域。記住,就像編程中的許多概念一樣,指向指針的指針可能一開始會讓人感到困惑,但通過練習,它們將變得 second nature。
以下是本文涵蓋的重點的摘要表格:
概念 | 語法 | 描述 |
---|---|---|
普通指針 | int *p; |
指向一個整數 |
雙重指針 | int **pp; |
指向一個指向整數的指針 |
解引用 | *p |
訪問 p 指向的值 |
雙重解引用 | **pp |
訪問 pp 指向的指針指向的值 |
地址運算符 | &x |
獲取 x 的地址 |
繼續練習,保持好奇心,並記住——每個專家都曾是初學者。快樂編程!
Credits: Image by storyset