函数的参数使用指针、地址、值的区别

一、目标

主要理清,在C语言中一个void方法里,当参数分别传入指针、地址、值三种选择时,我应该怎么选择传什么样的参数?哪种情况下结果会被带回?以及出现这种情况的原因。本篇文章我会用一个例子来说明。

例子:实现单链表的原地逆置

二、内容

变量定义

typedef struct LNode{
    int data;
    LNode *next;
}LNode,List;

(1) 情形一

//单链表的原地逆置
void reverse(List list){
    LNode* p;
    p = list.next;
    list.next = nullptr;
    while(p!=nullptr){
        LNode* temp = p->next;
        p->next = list.next;
        list.next = p;
        p = temp;
    }
}

结果是这样的:

(2) 情形二

将上述函数参数改为如下,方法体不动

void reverse(List &list)

得到正确结果

 (3)情形三

将函数参数改为指针,相应的list.xxx改为list->xxx

//单链表的原地逆置
void reverse(List *list){
    LNode* p;
    p = list->next;
    list->next = nullptr;
    while(p!=nullptr){
        LNode* temp = p->next;
        p->next = list->next;
        list->next = p;
        p = temp;
    }
}

得到正确结果

 

三、描述

1、情形一

传入的是List(头结点)。说明我对结点的改动是生效的,但是头结点(List)并没有把结果带回,头结点(List)的下个结点依然是0,应该是012,但0后面断了,是因为012的顺序发生了改变是生效的!变成了210。所以0后面不再有结点。

2、情形二

传的是List的地址头结点(List)的改动被带回。

3、情形三

传入的是指向List(头结点)的指针。头结点(List)的改动被带回。

、分析

1、情形一是值传递,形参与实参并不共用地址单元,是独立的。形参改变实参不受影响。

2、情形二是地址传递,形参与实参共用地址单元,或者说形参就是实参本身。

3、情形三

其实是值传递,不过传的是指针的值,然而我们的操作实际上并没有让指针发生改变(依然是指向头结点)。而是指针所指的地址内容发生变化(他们所指向的内存单元相同)。因此,借助形参list改变的内容可以被带回!

这也解释了情形一中。为什么在没被带回改变的情况下,却从 "头012",变化成了 "头0"。

因为012结点之间的顺序是用指针指向的。012已经变成210!只是形参头结点没有被带回实参,实参依然指向的是0,而0却已经是指向null的结点了!!
 

、总结

无论是传指针、地址还是值,都是为了也都是可以拿到内容去进行处理的。

我们应该关注的是,内容经过处理后的改变,是否能够被”带回“。

这本质又是一个形参与实参的问题了。

今后在定义函数参数时,根据实际情况,不再迷糊。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值