- #include <stdio.h>
- int main(){
- int a =100;
- int *p1 = &a;
- int **p2 = &p1;
- int ***p3 = &p2;
- printf("%d, %d, %d, %d\n", a,*p1,**p2,***p3);
- printf("&p2 = %#X, p3 = %#X\n",&p2, p3);
- printf("&p1 = %#X, p2 = %#X, *p3 = %#X\n",&p1, p2,*p3);
- printf(" &a = %#X, p1 = %#X, *p2 = %#X, **p3 = %#X\n",&a, p1,*p2,**p3);
- return 0;
- }
100, 100, 100, 100 &p2 = 0X28FF3C, p3 = 0X28FF3C &p1 = 0X28FF40, p2 = 0X28FF40, *p3 = 0X28FF40 &a = 0X28FF44, p1 = 0X28FF44, *p2 = 0X28FF44, **p3 = 0X28FF44
以上三级指针p3为例来分析上面的代码,***p3等价于*(*(*p3)), *p3得到的是 p2的值,也即 p1的地址;
**p3得到的是p1的值,也即a的地址,经过三次取值操作后,***a得到的才是a的值。
假设 a、p1、p2、p3 的地址分别是 0X00A0、0X1000、0X2000、0X3000,它们之间的关系可以用下图来描述:
方框里面是变量本身的值,方框下面是变量的地址。
void *malloc(size_t size),这个函数请求分配大小为size字节的内存,并返回指向该内存起始位置的指针
二级指针的应用:
看下面代码:有两个变量a,b,指针q,q指向a,我们想让q指向b,在函数里面实现
int a=10;
int b=100;
int *q;
void func(int *p)
{
p=&b;
}
int main()
{
q=&a;
func(q);
return 0;
}
最终的结构还是*q==a,并没有改变结果。
因为p 和q 都有自己的单元地址,p q 都指向a,调用函数之后,调用函数之后
只是改变了p单元存放的地址,并没有改变q单元存放的地址。
int a=10;
int b=100;
int *q;
void func(int **p)
{
*p=&b ;
}
int main()
{
q=&a;
func(&q);
return 0;
}
运行结果 *q=b;
因为函数在调用时较q的地址传递,
*p=q;同时也将q单元存放的地址改为&b
所以调用完函数后*q=b;
再看一个例子 内存分配
void my_malloc(char **s)
{
*s=(char *)malloc(100);
}
void main()
{
char *p=null;
my_malloc(&p);
if(p)
free(p);
*p=null;
}