认识指针基础概念

一、引出指针的概念

1.内存和地址

在计算机上,我们平常所说的内存与计算机的内存不一样,我们随口所说的通常是硬盘的储存
而通常所说的运行内存才是真正的内存,与CPU(中央处理器)相互协作
我们的电脑的内存通常有8GB/16GB/32GB等,我们如何有效的管理内存呢?
在这里插入图片描述

我们发散思维,这时候想,内存总容量固定大小我们通常不会一下子全部拿去上战场
这时我们需要把内存划分为一块一块的小空间,也称为内存单元,需要多少时就使用多少
噢,我们知道了内存是划分为一块一块的小空间,每一小块需要多大呢,这是我们得了解内存常见的单位:
在这里插入图片描述
首先要了解一个比特位是一个1或者0,八个比特位组成一个字节,然后就以2^10次方向上增长,我们这里只需要了解前两个
在这里插入图片描述
我们发现,如果每一个内存单元是一个比特位时,我们会发现就好比如一个宿舍一个人,这时我需要一个班级的人是不是需要去很多个宿舍找人,并且通常我们也不会用到一位一位的操作
这时,我们联合之前所学的类型发现,它们都是以字节为基础的,我们会想到是不是每一个内存单元都是一个字节的
我们终于找到一个合理的中间值了,一个内存单元是一个字节,就好比如一个宿舍八个人
我们回想起来,一个宿舍如果没有门牌号,是不是不好找到那个宿舍,内存单元是不是也存在这种问题
这时候我们想到是不是可以上一个门牌号给那个宿舍,内存单元如果上门牌号呢?
我们引出一个概念叫地址,每一个内存单元都有一个地址
在这里插入图片描述
CPU(中央处理器)怎么找到内存里面那一小块内存单元的呢,这时我们找到了CPU与内存连接的地址总线
地址总线在电脑上展现出来的形式是,电脑是多少位操作系统,如第一关图所示
X64是64位操作系统,地址总线就是64根,一根线有两种状态0或者1,可以查询2^64个内存单元
同理X86是32位操作系统,可以查询2^64个内存单元,我们可不能理应认为是86位操作系统

2.取地址符‘ & ’和解引用操作符‘ * ’

我们知道了内存和地址的关系,也懂得知道地址可以找到那内存单元
这时候我们发展如何使用地址找到我们存储的数据
首先,我们知道平常使用变量的打印是这样的
在这里插入图片描述
可以看到是单纯的对于变量a内容的打印
这时加入我们的取地址操作符‘ & ’并且使用%p(十六进制)打印来尝试
在这里插入图片描述
我们可以看到这一串陌生的数字,这就是变量a的地址
这时我们模糊的感觉到,原来取地址操作符‘ & ’可以取出变量的地址
在这里插入图片描述
一个变量有三个部分,分别是它的名字,它的存储空间,它的存储所在的地址
可以看到,取地址操作符‘ & ’确实是取出变量a的地址
当然,每次重新编译链接重新运行变量a的地址会改变
这时我们又要想,怎么把取出来的地址储存起来
C语言给了一个存储地址的变量名为指针
我们先了解指针的定义
在这里插入图片描述
这时可以使用取地址操作符‘ & ’把地址存入指针变量里了
我们可以看到当打印地址时&a和p的内容一样,说明p里面确实存了a的地址
在这里插入图片描述
我们这知道了怎么存进去,接下来该用解引用操作符 ‘ * ’ 来间接访问变量a了
可以看到,使用%d打印,并且在p前面加上‘ * ’就可以打印a里面的值了
在这里插入图片描述
这样,我们看到使用指针可以间接访问变量a
我们也可以使用解引用操作符‘ * ’来访问并且改变变量a的值
在这里插入图片描述

二、指针的类型与一维数组和指针的关系

1.指针的类型

通常来说有什么数据类型就会有对应的指针来指向这个数据类型定义的变量
比如说用整型定义变量,就可以定义一个指向整型的指针
还有其他的浮点型、字符型,甚至可以指向指针或其他意想不到的
在这里插入图片描述
值得一提的是,指针变量也是变量,它与普通类型变量的区别指针变量是存的是十六进制的地址,而普通类型的变量存的是一个值
指针变量存储可以给一个十六进制的值(0x开头)
如果给普通不带0x开头的数值就会认为类型不匹配,一个是指针类型,一个是数值类型
在这里插入图片描述
如果给的是十六进制数,输出也只能用%p格式输出,把此认为是地址输出

2.一维数组与指针的关系

我们数组的定义与使用通常是这样子的
在这里插入图片描述
但如果说数组还能换指针的方式来实现你肯定觉得惊讶
我首先要告诉你,数组名就是首元素的地址,意思是它代表着第一个元素的地址
在这里插入图片描述
下面的arr[10]代表数组是十个元素,上面的arr只是一个名字,它指向的是第一个元素
如果把它当成指针,它存的就是第一个元素的地址
在这里插入图片描述
这里说的第一个元素不是下标1元素,而是下标0元素,每个人习惯不同
下面利用指针的解引用与指针的偏移来实现数组下标
在这里插入图片描述
所以数组每个元素都有它的地址,可以用下标访问,也可以用指针偏移访问
这也变相证明,为什么地址都是从0开始的
数组名就是首元素地址,如果从1开始,就会出现这样:
arr[1] 是等于 arr 呢 还是 arr+1
但是加1又不符合数组名就是首元素地址
不加1又不符合下标与数组名同步

三、函数参数中的传值与传址

1.传值和传值的差别

传值通常实现一个函数时,函数的形参列表是普通数据类型定义来使用
在这里插入图片描述
我们看到在func函数里面交换x和y并不会改变主函数a和b
如果只是传值,还有一个口诀就是:
形参是实参的一份临时拷贝,修改形参并不会改变实参
以上面那个来说,我在func函数里面随便玩x和y都不会改变主函数里面的a和b
如果我需要改变函数传过来的那个实参呢?
或者说关联func函数里的xy间接改变ab呢?
这时我们引出地址,并以地址为基础间接改变a和b
在这里插入图片描述
我们可以看到传的是地址过去,用指针接收
使用解引用可以跟寻地址找到ab存数值的那片空间并进行改变
在这里插入图片描述
传址并不是使用在简单的普通数据类型上,可以传数组首元素地址然后地址偏移访问
还可以是其他的自定义数据类型传址操作
在这里插入图片描述
千万别越界,数组只有十个空间,别访问了不是你的空间
完!
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值