今天我想向大家介绍形参传一级地址还是二级地址的情况。

首先,来个栗子

void change(int *p)                       地址:3000>>2000           5      地址:2500

{                                                   变量:p                                        变量:*p
p = (int *)malloc(sizeof(int));
*p = 5;

}

void main()                                   地址:2000

{                                                   变量:num

int num = 10;

change(&num);

printf("num = %d",num);

}

  结果打印出来num = 10,子函数的调用并没有改变num的值,我们假设主函数变量地址为2000,子函数变量地址为3000,主函数中将num的地址当作形参传送给子函数,很明显,子函数的地址由3000变为2000,虽然子函数拥有了对子函数的控制权,但是num并没有出现修改成5的迹象。

  这是当然了,因为子函数中重新申请了变量p的地址,这个地址并不是我们能控制的,假设申请到的地址是2500,那么*p = 5这条指令是存放在地址2500中的,跟子函数和主函数地址完全不一样啊。

  所谓道高一尺魔高一丈,就是为了解决这种情况,便出现了形参为二级地址的方法,栗子如下:

  

void change(int **p)                        地址:3000>>2010         5    地址:2500

{                                                      变量:p                                   变量:*p
*p = (int *)malloc(sizeof(int));
**p = 5;

}

void main()                                            地址:2000

{                                                             变量:num

int num = 10;
int *a = #

change(&a);                                         地址:2010>>2500

printf("num = %d",*a);                           变量:*a

}

  打印出来就是妥妥的num = 5了,原因也是之前讲到的地址问题,然而,这一个相比之前,就有些复杂了,跟上一个相比,区别在于子函数的形参由一级指针变成了二级指针,也正因为是二级指针的原因,主函数必须要定义一个指针变量*a存放变量num,再把*a的地址当作形参传给子函数,才是二级地址的格式。

  假设*a的地址是2010,传给子函数,子函数变量的地址由3000变成2010,子函数中重新申请p的地址,此时*p = (int *)malloc(sizeof(int))中的*p就不是我们平时见到的指针变量了,而是二级指针的地址,假设申请到的同样是2500,是不是就可以得知*p = 2500,推算可得同时*p = &a,推算可得**p = *&a = a。

  至此,便可知道,主函数变量*a的地址已经和子函数新地址2500一样了,那么地址2500中进行的**p = 5结果也会传给*a,*a的值就从10变成了5,完成了修改。

  可能我说的有点啰嗦复杂了,那么来做一个简洁一点的小总结吧。

  (1)子函数中改变普通变量的值,形参得用一级地址。

  (2)子函数中改变指针变量的值,形参得用二级地址。

posted on 2018-08-28 21:11  五月525  阅读(275)  评论(0编辑  收藏  举报