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[] = {"苹果", "香蕉", "樱桃"};
char **ptr = fruits;
for(int i = 0; i < 3; i++) {
printf("%s\n", *ptr);
ptr++;
}
return 0;
}
输出:
苹果
香蕉
樱桃
在这个例子中,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