函数传参——一级指针与二级指针

我们先来看一级指针作为参数:

float *s = NULL;         //①

 void fun(float *p1,float *p2, float *s)          //②

{

       s=(float *)calloc(1,sizeof(float));        //③

       *s=*p1+*p2++;

}

调用函数fun(a, b ,s);

        上述代码看似将一级指针s作为参数传入到fun函数内部,实际上并不是。因为①中的指针s与②中的参数指针不是一个同一个指针。如下图:

①中的指针s与②中的参数指针直接的关系如下:

 

由于fun函数中在堆空间中申请一块空间,关系如下:

         从图中可以看到,fun()函数中的一级指针的指向被改变了。但是,无论我们在fun()函数中怎么折腾,始终都只能改变栈区指针的指向和堆空间中的值,而全局变量区中的指针的指向始终指向NULL,不会受丝毫改变。而且,当fun()函数执行完后,栈区中的一级指针就会被释放掉,那么此时我们也就再也无法寻找到这个一级指针指向的堆空间了。

        这样的传参看似是地址传递,实际上它是值传递,因为它具有值传递的特性

我们再来看一级指针地址(即二级指针)作为参数:

float *s;         //①

 void fun(float *p1,float *p2, float **s         //②

{

       *s=(float *)calloc(1,sizeof(float));        //③

       **s=*p1+*p2++;

}

调用函数fun(a, b ,&s);

        我们可以看到,地址传递是一环扣一环。

         二级指针**s保存的是全局变量区中一级指针*s的地址,所以,二级指针变量就指向全局变量区的一级指针。所以,fun()函数中,s表示的是栈区中的二级指针。而s的解引用*s,则表示的是二级指针指向的一级指针,注意:该一级指针是在全局变量区而不是在栈区。*s的解引用**s,就表示一级指针指向的空间。

        fun()函数中, 语句:*s=(float *)calloc(1,sizeof(float)); ,申请一个堆空间,将堆空间的地址交给*s来保存,由上述所知,一级指针*s不是在fun()中,但是我们却可以通过对fun()函数内的二级指针s进行解引用,来改变栈区外面一级指针*s的指向。这个就是地址传递的特性

        所以,地址传递:

                                 ①对于普通变量,则用它的地址作为参数(即一级指针)。

                                 ②对于一级指针变量,则用它的地址作为参数(即二级指针)。

        值传递与地址传递的区别就是,值传递,传递的是拷贝的数据副本。而地址传递,传递的则是变量所在的位置。

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值