保持空杯心态,在了解的基础上明白,继而熟悉,终于熟练。
今天分享一个多级指针的例子,看你有没有被绕晕?
题目:三级指针传递和修改
问题:定义一个函数 modifyValue,接受一个三级指针(int ***),并将所指向的值修改为 100。在 main 函数中测试这个函数。
示例代码:
#include <stdio.h>
#include <stdlib.h>
void modifyValue(int ***ptr)
{
***ptr = 100; // 直接修改所指向的值
}
int main(void)
{
int value = 42;
int *p = &value;
int **pp = &p;
printf("Before modification: %d\n", value);
modifyValue();这个位置该传入什么呢?才能满足题意
printf("After modification: %d\n", value);
return 0;
}
函数括号里面应该传入什么呢?
在 modifyValue
中,ptr
是 int ***
类型的指针。这意味着:
*ptr
是一个int **
类型的指针(即pp
)。**ptr
是一个int *
类型的指针(即p
)。***ptr
是一个int
类型的值(即value
)。
调用 modifyValue
函数
要理解正确的调用方式是 modifyValue(&p);
,我们需要知道 modifyValue
的参数类型和你传递的实参的关系。
-
modifyValue(&p);
解析:&p
是int **
类型的地址,即pp
的地址。- 传递
&p
给modifyValue
,这样ptr
在modifyValue
中指向int **
类型的指针(即pp
)。 - 在
modifyValue
中,*ptr
解引用得到p
,**ptr
解引用得到value
。因此,***ptr
实际上是value
,可以直接修改它。
-
错误的调用方式
modifyValue(&pp);
:&pp
是int ***
类型的地址。将&pp
传递给modifyValue
,ptr
在modifyValue
中指向int ***
类型的指针。- 在
modifyValue
中,*ptr
解引用得到pp
,**ptr
解引用得到p
,而***ptr
也会得到value
,但这不是你真正意图的修改,因为&pp
是一个不适合此函数的实参。
3.为什么&pp 是 int *** 类型的地址?
&pp
是 int ***
类型的地址,因为 pp
本身是 int **
类型的变量。让我们详细拆解一下:
-
变量
pp
的类型:pp
是int **
类型的指针,指向int *
类型的指针(即p
)。
-
取地址操作:
&pp
是取pp
变量的地址。&pp
的类型是int ***
,因为pp
是int **
类型的变量,所以&pp
是一个指向int **
的指针,也就是int ***
类型的指针。
类型总结
pp
的类型是int **
。&pp
的类型是int ***
,这是因为&pp
是pp
的地址,pp
是int **
类型。
4.为什么pp 是 int ** 类型的指针,指向 int * 类型的指针?
-
value
是一个int
类型的变量。p
是一个指向int
的指针,即int *
。pp
是一个指向int *
的指针,即int **
。
-
指针的层次:
p
存储了value
的地址,所以p
是一个int *
类型的指针。pp
存储了p
的地址,所以pp
是一个int **
类型的指针。
理解 pp
的类型
-
p
的类型:p
是int *
,它保存了value
的地址。也就是说,p
指向一个int
类型的值。 -
pp
的类型:pp
是int **
。它保存了p
的地址。由于p
是int *
类型,所以pp
是一个int **
类型的指针。这个类型的指针指向另一个指针,即int *
。
总结
pp
是int **
类型的指针,因为它指向一个int *
类型的指针(即p
)。pp
的内容是p
的地址,而p
是int *
类型的,因此pp
指向一个int *
类型的地址。
这个多级指针的层次关系是这样构成的:
pp
→p
→value
因此,pp
是 int **
类型,它指向 int *
类型的指针(即 p
)。