c语言函数传递二重指针,C语言二重指针的运用

C语言二重指针的运用

『摘要』本文主要通过实例展示C/C++中二重指针的用法和用途,对于诸如二叉树等递归定义的数据结构有一定的指导作用。

【关键字】:C/C++、二重指针、递归

本人最近想实现一个B+树,虽然对B+树的理论有一定的认识,但由于考研花去大量时间复习功课,对C的一些细节有所遗忘,因此决定从二叉树的实现开始。但刚写完二叉树的创建函数且在编译通过之后,调试时却出现了问题。二叉树是一种递归定义的数据结构,因此其创建函数也必定是递归的。其创建函数描述如下:

fb9535a58b07f37459a484363a6fae54.png

图1二叉树创建函数

理论上没有错误,同时在创建二叉树时也能成功,但通过本人编写的先序遍历该二叉树时,却显示0,即空的二叉树,相关操作代码如下:

//具体的操作步骤

TREE tree = 0; //TREE为二叉树结构体的指针型别

createBinaryTree(tree);

//先序遍历

由于结果错误,因此开始调试,通过观察发现当createVinartTree(tree)操作完成后tree的属性仍然为0,即仍然tree=0。后来又通过仔细分析,发现问题出在函数的参数上。虽然该函数传入的是指针型别,属于实参,但是该函数内部主要以原指针作为操作对象,因此相对于指针来说,传入的只是结构体指针的形参。所以,在函数内部操作的只是一个副本,因此二叉树的创建失败。

为了解决这个问题,笔者决定验证自己的想法是否正确,于是写了如下一段测试代码,代码如下:

//版本1

typedef struct student {

char* name;

int age;

}Student,*STUDENT;

void getInstance(STUDENT s);

int main(){

Student* st = 0;

printf("指针st的地址=%d\n",&st);

getInstance(st);

printf("st新实例的地址=%d\n",st);

return 1;

}

void getInstance(STUDENT s){

printf("指针S的地址=%d\n",&s);

s = (Student*)malloc(sizeof(student));

printf("s新实例的地址=%d\n",s);

}

这个函数的传值形式与之前二叉树的函数差不多,因此可以类比,具体运行之后得到的记过是(如图):

e109b25651c83bea4e3b750a2a9caae5.png

图2版本1的运行结果

结果很显然,指针传入函数之后产生了一个新的副本,对副本的任何操作,都不会影响到原指针指向的结构体,与二叉树创建失败类似,目的指针的副本指向了目标结构体,产生了内存泄漏。

这个问题的解决也十分的简单,将结构体的指针作为实参传入函数即可,这样就可以直接操作目标指针,也就不会出现错误的结果。运用二重指针可以轻松实现,具体修改如下:

//版本2

typedef struct student {

char* name;

int age;

}Student,**STUDENT;

void getInstance(STUDENT s);

int main(){

Student* st = 0;

printf("指针st的地址=%d\n",&st);

getInstance(&st);

printf("st新实例的地址=%d\n",st);

return 1;

}

void getInstance(STUDENT s){

printf("指针S的地址=%d\n",s);

*s = (Student*)malloc(sizeof(student));

printf("s新实例的地址=%d\n",*s);

}

修改部分如黑体部分所示,具体的运行结果如下图:

7c84412fb2ea160d46a16daddc008037.png

图3版本2的运行结果

测试成功,函数内部操作的指针就是实际传入的指针,即通过二重指针实现了目标操作指针的实参传递,因此能达到预想的结果。这也说明了二重指针的实际用处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值