1.什么是指针
普通指针
首先先理解变量
int a=1; printf("%p\n",&a); printf("%d\n",a);
这里给大家补充一个知识点,%p是查看地址
006dfe9c
1
这里的006dfe9c是变量a的地址,而1是这个地址(006dfe9c)存的值
我们讲繁杂的地址值用抽象的a来表示,而编译器会自动还原a->006dfe9c
那么,指针呢?
这里说明一点,*有取地址的做用,称为升维。&在此处有取地址的作用,称为降维。
可见,指针p具有自己的地址,而指针p地址中存的地址,可以由用户来修改,p=&a就是取a的地址,赋值给p,如图
int* p=NULL; printf("&p=%p\n",&p); printf("p=%d\n",p); p=&a; printf("&p=%p\n",&p); printf("p=%p\n",p); printf("*p=%d\n",*p);
&p=006dfe98
p=0
&p=006dfe98
p=006dfe9c
*p=1
指针作为形参
#include<bits/stdc++.h> void example(int *q){ printf("q=%d\n",*q); printf("&q=%p\n",&q); } int main(){ int a=1; int *p=NULL; p=&a; printf("p=%d\n",*p); printf("&p=%p\n",&p); example(p); }
先来看结果
p=1
&p=006dfe98
q=1
&q=006dfe80
我们发现,p,q的值是一样的,为什么p,q自身的地址不一样呢?因为函数传递的时候是:"值传递"而非“地址传递”,如图
2.什么是引用
int a=1; int &b=a; printf("%d\n",b); printf("%p\n",&a); printf("%p\n",&b);
1
006dfe98
006dfe98
引用符号是&,这里是b其实就是a 的别名,如果a是某个人的大名,那么b就是某个人的小名
所以b的值就是a的值,b的地址就是a的地址
看,就是把b挂了上去!
但是,不能再用b引用别人了,意思是这个小名是a独有的,别人不能用这个小名
显然这个操作是不合法的
引用的作用
我们知道,函数值传递不会改变原来的地址内存的值
而引用可以直接把地址传进去, 如图
3.指向引用的指针
除了引用,指针也可以交换a,b的值,如图
指针传给函数里面,实质上是把指针指向的地址(指针的内容)传进去,那么只能修改这个地址单元里面的东西,而不能修改这个地址
而引用,是这个变量的地址,那么指向引用的指针,就可以修改,指针指向的地址,也可以修改指向的地址里面的地址(内容)
如何理解上述内容呢,来看实例
这就是指向引用的指针(*&)的好处(既可以修改存储的地址,又可以修改存储地址的内容),为什么这样说呢,从图中,我们可以看到p1,p3的自身的地址是不会变的,但是,
p1,p3其中存的地址(&a,&c),是可以被改变的
解释:如果单用指针作为形参,那么传进去的是其中的地址,只能修改p1中地址的内容(&a) ,意思就是只能对a的值修改,而如果想让p1指向b,指向c,在指针作为形参中是做不到的
而为什么现在可以修改p1存的内容了呢,想让p1=&a,想让p1=&b,都可以,这是因为引用,正因为有了引用,函数形参传进去的是p1这个单元的地址,而非这个单元存的地址
那么可以会有很多同学问了,*&我怎么没见过,用在哪里,就目前我见过的而言,用在链表,如图
这里的形参是指针,红色箭头上一句是合法的,而红色箭头那一句是非法的
taillist->next=newlist这个操作,其内部操作是,用tailist里面存的地址,取出存的地址的next单元进行赋值操作
而talilist=taillist->next这个操作,其内部操作是,修改"taillist"(假)里面存的地址,但是这个修改是假的,因为函数传递的时候是:"值传递"而非“地址传递”,即函数体中的taillist的本身地址,和函数体外面的taillist的本身地址,是不一样的,一样的是taillist里面指向的地址,如有不懂,请回头看上文指针作为形参的解释
如果本文有错误,欢迎提出