关于数据结构的&符号所带来的诸多疑惑(未完待续)

       很多同学在学习数据结构的时候,会困惑&符号的作用,特别是对于链表等数据结构的基础操作,有的有&符号,有的又没有,到底这是什么情况呢?别着急,看完这篇文章,你肯定就清楚了。

       先说说&这个符号,相信学了C语言的同学都见过这个符号,这不是取地址符号吗?在位运算中也会有这个符号,没错。但是同一个符号用在不同的地方是有不同的表达的,而我们今天要讨论的,是作为引用符号。先不说引用符号&的作用具体是什么,先要注意的一点是,&引用是一个C++的语法,并不是C语言的。如果你想使用&引用符号,就需要把源文件保存为.cpp格式,然后编译运行才可以通过。严蔚敏书虽然叫做C语言版,但是人家在开头就说了,她的代码,是伪代码。她用&符号是因为&符号在C++中就代表了这个意思。她书中对&标记的参数,叫做,需要以引用的方式进行传递,那么我们就先来聊聊这个问题。

       什么是引用机制。我们来看看c语言的一个经典问题。       

void swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}

int main()
{
   int a = 5;
   int b = 3;
   swap(a, b);
   return 0;
}

这是一个引入指针的经典问题,通过这种方式,并不能交换a和b的值,这是为什么呢?因为c语言的函数都是值传递的。看过书的同学知道,有实参和形参的概念。实参是指传入这个函数的实际参数,在这个例子里就是a和b,而形参是指在函数中的你能够访问到的参数值,这里是x和y,所谓的值传递,是指你使用的 x和y实际上是复制了a和b的值,并不是直接使用a和b,所以你无法通过交换x和y来交换a和b。

       所以我们引入了指针的概念,代码如下

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
   int a = 5;
   int b = 3;
   swap(&a, &b);
   return 0;
}

基础不好的同学,看到这段代码直接就傻了,因为用到了指针,指针是个更大的专题,所以我不在这里讲,如果你对这段代码有些吃力,建议先复习复习指针的概念,再来继续看。

       为什么这么做就能够交换a和b的值了呢,难道用指针,就可以避免参数的值传递?并不是的,实际上指针也发生了值传递。

       x复制了a的地址,y复制了b的地址,然后在函数里你注意,交换的是*x和*y,也就是地址指向的内容。这个机制很重要,就是间接引用,如果你清楚指针和间接引用,你就知道为什么这么做是可行的。

       一定要注意一点,交换指针和交换指针的内容是不同的。因为接下来我们就要举一个指针的例子。


void CreateList(ListNode* L)
{
    L = (ListNode*) malloc(sizeof(ListNode*));
}

int main()
{
    ListNode* head;
    CreateList(head);
    return 0;
}

很熟悉吧,很多新手同学初始化一个链表线性表都是这么操作的,结果就各种报错。实际上你运行了以后会发现,head并没有被分配空间,而是一个野指针。其实这里只是比较绕,但其实还是值传递的问题。

       首先L 复制了 head的值,这个结构体指针是怎么复制的呀,其实指针的本质都是一个数值,指向了一个结构体的首地址。这个时候L和head指向的是不是同一个地方呢?是的,没问题。问题就在里边。malloc会分配一块新的空间,并且形参L指向了这个空间。注意这个时候head指向的还是外边的野指针。你改变L的指向并不会对head造成什么影响。

       

仔细理解理解这段代码!

所以同学们一定要去弄清楚,去想清楚,函数的本质都是传值(复制),在此基础上通过指针的间接引用,来改变实参的值。不要被所谓的传址所迷惑。那都是编造出来的融合概念。理解了指针的用法和函数的本质,剩下的很好办

那接下来说说&符号,我们叫做引用,刚开始接触这个概念可能比较迷惑,而这个概念在很多高级语言里非常基础,因为涉及到了面向对象的知识,但是我们不希望引入太多。

可以这么简单的理解,C++的&符号在函数中作为引用符出现的时候,就不是复制了,而是转移。从机制上来说,很多人把&符号叫做取别名。你理解了吧。只是给变量换了个名字。画图的话就是下边这个样子

它们代表的其实是一个变量,内存地址也是一样的,所以你在函数里的任何行为,都直接能够影响到外部元素的变化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值