指针

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里面指向的地址,如有不懂,请回头看上文指针作为形参的解释

如果本文有错误,欢迎提出

posted @ 2021-04-20 22:02  cheems~  阅读(40)  评论(0编辑  收藏  举报