假设有这样一段代码,p2(二级指针)指向p1(一级指针),p1指向a,a就是一个普通的整型变量,a的值为100。
void main(void)
{
int a = 100;
int *p1 = &a;
int **p2 = &p1;
}
假设a的地址为0x0000,p1的地址为0x0004,p2的地址为0x0008,那么就有这样一个内存和值的映射表。
变量 | p2 | p1 | a |
---|---|---|---|
值 | 0x0004 | 0x0000 | 100 |
地址 | 0x0008 | 0x0004 | 0x0000 |
对一级指针p1取值,就是*p1=*(0x0000)=取地址0x0000的值=a=100
对二级指针p2取值,就是*p2=*(0x0004)=取地址0x0004的值=p1=0x0000
由此可以知道,*的结果就是前一级的值,那么这个有什么用呢?
假设我们有这样一个需求,就是在函数内部为一个指针分配内存,并且要在函数外部生效。这时候就需要用到二级指针了。
#include "stdio.h"
#include "stdlib.h"
int a = 100;//全局变量a
void malloc_p(int **p2)//二级指针p2
{
*p2 = &a;
}
int main(void)
{
int *p1 = NULL;//一级指针p1
malloc_p(&p1);
printf("*p1 = %d\r\n", *p1);
return 0;
}
这一段代码的作用是什么呢?其实就是将p2,p1和a进行绑定。
我们来分析一下,按照代码的运行过程,首先
int a = 100;
mina函数里面的int *p1 = NULL;
函数里面的int **p2
因此内存关系就是这样,这时候p2,p1,a之间还没有建立任何联系,他们彼此独立。
变量 | p2 | p1 | a |
---|---|---|---|
值 | 未知 | NULL | 100 |
地址 | 0x0008 | 0x0004 | 0x0000 |
当调用malloc_p(&p1)
函数时,其实就是int **p2 = &p1;
这时候建立了p1和p2的关系,p2存放的是p1的地址,*p2就是p1的值。
变量 | p2 | p1 | a |
---|---|---|---|
值 | 0x0004 | NULL | 100 |
地址 | 0x0008 | 0x0004 | 0x0000 |
当执行*p2 = &a;
语句后,其实是*p2 = p1 = &a;
这时候就建立了p2,p1和a之间的关系
变量 | p2 | p1 | a |
---|---|---|---|
值 | 0x0004 | 0x0000 | 100 |
地址 | 0x0008 | 0x0004 | 0x0000 |
最后,在函数malloc_p(&p1)
运行完成以后,就可以通过p1来操作a的那块内存了。