二级指针与多级指针

1.二级指针基本概念(指针变量地址的数据类型)

和一级指针的区别就是取完一次地址识别到的是地址,还可以进行取地址,而一级指针取完一次地址识别到的是地址中的值了,值是不可以再进行取地址。

这里让我们花点时间来看一个例子,揭开这个即将开始的序幕。考虑下面这些声明:

int a = 12;

int *b = &a;

它们如下图进行内存分配:

假定我们又有了第3个变量,名叫c,并用下面这条语句对它进行初始化

c = &b;

它在内存中的大概模样大致如下:

问题是:c的类型是什么?显然它是一个指针,但它所指向的是什么?变量b是一个“指向整型的指针”,所以任何指向b的类型必须是指向“指向整型的指针”的指针,更通俗地说,是一个指针的指针。

它合法吗?是的!指针变量和其他变量一样,占据内存中某个特定的位置,所以用&操作符取得它的地址是合法的。

那么这个变量的声明是怎样的声明的呢?

int **c = &b;

那么这个**c如何理解呢?*操作符具有从右想做的结合性,所以这个表达式相当于*(*c),我们从里向外逐层求职。*c访问c所指向的位置,我们知道这是变量b.第二个间接访问操作符访问这个位置所指向的地址也就是变量a.指针的指针并不难懂只需要留心所有的箭头如果表达式中出现了间接访问操作符你就要随箭头访问它所指向的位置

2. 二级指针做形参输出特性

说明一下:a[2]和*a+2一样的

二级指针做参数的输出特性是指由被调函数分配内存,主调函数使用。

//被调函数,由参数n确定分配多少个元素内存

void allocate_space(int **arr,int n){

//堆上分配n个int类型元素内存

int *temp = (int *)malloc(sizeof(int)* n);

if (NULL == temp){

return;

}

//给内存初始化值

int *pTemp = temp;

for (int i = 0; i < n;i ++){

//temp[i] = i + 100;

*pTemp = i + 100;

pTemp++;

}

//指针间接赋值

*arr = temp;

}

//打印数组

void print_array(int *arr,int n){

for (int i = 0; i < n;i ++){

printf("%d ",arr[i]);

}

printf("\n");

}

//二级指针输出特性(由被调函数分配内存)

主调函数

void test(){

int *arr = NULL;

int n = 10;

//给arr指针间接赋值

allocate_space(&arr,n);

//输出arr指向数组的内存

print_array(arr, n);

//释放arr所指向内存空间的值

if (arr != NULL){

free(arr);

arr = NULL;

}

}

3. 二级指针做形参输入特性

二级指针做形参输入特性是指由主调函数分配内存,被调函数使用它

//打印数组

void print_array(int **arr,int n){

for (int i = 0; i < n;i ++){

printf("%d ",*(arr[i]));

}

printf("\n");

}

//二级指针输入特性(由主调函数分配内存)

void test(){

栈区申请数据内存

int a1 = 10;

int a2 = 20;

int a3 = 30;

int a4 = 40;

int a5 = 50;

int n = 5;

int** arr = (int **)malloc(sizeof(int *) * n);

arr[0] = &a1;

arr[1] = &a2;

arr[2] = &a3;

arr[3] = &a4;

arr[4] = &a5;

打印堆区数据

print_array(arr,n);

释放堆区

free(arr);

arr = NULL;

}

4 强化训练_画出内存模型图

void mian()

{

//栈区指针数组

char *p1[] = { "aaaaa", "bbbbb", "ccccc" };

//堆区指针数组

char **p3 = (char **)malloc(3 * sizeof(char *)); //char *array[3];

int i = 0;

for (i = 0; i < 3; i++)

{

p3[i] = (char *)malloc(10 * sizeof(char)); //char buf[10]

sprintf(p3[i], "%d%d%d", i, i, i);

}

}

5 多级指针

将堆区数组指针案例改为三级指针案例:

//分配内存

void allocate_memory(char*** p, int n){

if (n < 0){

return;

}

char** temp = (char**)malloc(sizeof(char*)* n);

if (temp == NULL){

return;

}

//分别给每一个指针malloc分配内存

for (int i = 0; i < n; i++){

temp[i] = malloc(sizeof(char)* 30);

sprintf(temp[i], "%2d_hello world!", i + 1);

}

*p = temp;

}

//打印数组

void array_print(char** arr, int len){

for (int i = 0; i < len; i++){

printf("%s\n", arr[i]);

}

printf("----------------------\n");

}

//释放内存

void free_memory(char*** buf, int len){

if (buf == NULL){

return;

}

char** temp = *buf;

for (int i = 0; i < len; i++){

free(temp[i]);

temp[i] = NULL;

}

free(temp);

}

void test(){

int n = 10;

char** p = NULL;

allocate_memory(&p, n);

//打印数组

array_print(p, n);

//释放内存

free_memory(&p, n);

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值