背景:
在学习uC/os ii源码时,遇到了关于二级指针这样的例子,当时自己想了好久,现在分享出来供大家参考。
void *addr;
void **plink;
addr = &ADDR;
-------------------------------
plink = (void **)addr;
pblk = (INT8U *)((INT32U)addr + blksize);
for (i = 0; i < (nblks - 1); i++) {
*plink = (void *)pblk;
plink = (void **)pblk;
pblk = (INT8U *)((INT32U)pblk + blksize);
}
*plink = (void *)0;
分析上述程序:
首先plink是一个二级指针,plink=(void **) addr,addr是一级指针,需要注意的是(void **)addr的值是addr的值,也就是ADDR的地址。(void **)addr和(void )addr是一个值,此时,可以暂时理解为plink和plink指向同一个区域。
*plink=(void )pblk, 改变的是plink的指向,*plink指向了pblk的区域,此时plink还没有改变指向。plink = (void **)pblk,到这里才改变的是plink的指向。
之前遇到二级指针用法都是这样的:
void a;void *b;void **ptr;
b = &a; ptr = &b;
而这个例子中最难理解的地方在于plink = (void **)addr,plink是一个二级指针,addr是一个一级指针,强制类型转换后,plink到底指向哪里,plink的值又是什么,是非常疑惑的。我个人的理解是,因为addr是一级指针,二级指针plink兼容一级指针addr,这个时候plink当成一级指针来用。plink等于addr,**plink就会报错。但是本质还是二级指针,所以plink被赋值为(void *)pblk的时候,*plink的值还是会发生变化改变指向。
附上个人验证的程序
/*********************************************************************
* Author : liu
* Last modified : 2023-05-16 18:26
* Filename : main.c
* Description :
* ******************************************************************/
#include "stdio.h"
int main(){
int *a;
int *c;
int b;
int d;
int **ptr;
b = 321;
d = 123;
c = &d;
a = &b;
printf("&a %x\n", &a);
printf("a %x\n", a);
printf("(int *)a %x\n", (int *)a);
printf("(int **)a %x\n", (int **)a);
printf("a addr %x\n", a);
printf("c addr %x\n", c);
printf("b addr %x\n", &b);
printf("d addr %x\n", &d);
ptr = (int **)a;
printf("ptr %x\n", ptr);
printf("*ptr %x\n", *ptr);
//printf("**ptr %x\n", **ptr);
*ptr = (int *)c;
printf("*ptr = (int *)c\n");
printf("ptr %x\n", ptr);
printf("*ptr %x\n", *ptr);
printf("**ptr %x\n", **ptr);
ptr = (int **)c;
printf("ptr %x\n", ptr);
printf("*ptr %x\n", *ptr);
return 0;
}