前言:我学C语言之前,有很多人对我说:“学到指针就老实了”,现在我学到了指针,让我看看我有没有真的老实
内存和地址
内存
CPU在处理数据的时候,需要的数据是从内存中读取的,处理后的数据也会放回内存,那么这些内存空间怎么高效的管理呢?
内存的解决方案就是把内存划分为一个一个内存单元:每个内存单元的大小为一个字节
每个内存单元都有编号。在C语言中,我们把地址称为指针
我们可以这么认为:内存单元的编号 = = 地址 = = 指针
计算机如何编址
在计算机中,地址不是将每个字节记录下来,而是通过硬件设计完成,是通过硬件设备给每个内存单元编址
计算机中有很多线,将很多元件连接起来,就比如内存和CPU,他们交互的次数很多,就必然有线将他们连接起来,而这里就有“地址总线”
地址总线的作用就是编写地址,32位计算机就有32根地址总线,他们能表示“0或1”,所以32根地址总线就能表达2的32次方个地址
地址信息被下达给内存,在内存上就能找到该内存对应的数据,再将数据传给CPU内寄存器
指针变量和地址
取地址操作符
在了解了内存和指针的关系后,我们再看C语言,C语言中创建变量就是向内存申请空间
就比如要创建一个整型变量,就要要申请四个字节来储存变量,并且四个字节连续
而取地址操作符&
,就是取变量的地址,但值得注意的是,取地址操作符只能取用连续地址的第一个地址,剩下的地址可以推导出来
指针变量和解引用操作符
取地址讲完了,那么取出来的地址应该存在哪里呢
答案就是:指针变量
指针变量是专门存储指针的变量,也可以理解为专门存储地址的变量
指针变量长这样int * pa = &a
指针变量类型
指针变量也是变量,变量就有类型,那么怎么观察指针变量的类型嘞
在int * pa = a
中,*是在说明pa
是指针变量,前面的int
是在说pa指向的是整型int
变量
可以理解的是,pa
这个指针变量中储存的是指向变量(就是取地址变量)的地址
解引用操作符
我们把地址保存起来,那么我们该怎么使用呢?
其实拿到了指针,就能知道指针所指向的对象
这时我们就要了解一个操作符:解引用操作符*
*pa
的意思就是,通过pa
中存放的地址指向a
在这时候,*pa
其实已经可以等于a
了
指针变量的大小
假设32位机器需要32根地址总线,每个总线1或0,那么32根地址总线产生的2进制位序列当做一个地址,那么一个地址就是32个bit位,需要4个字节才能存储
一个地址的大小就是4个字节,指针变量是用来存放地址的,那么一个指针变量的大小就是4个字节的空间
同理,64位机器,指针变量大小就是8个字节
注意指针变量的大小和类型的是无关的,只要是指针类型的变量,在同一平台下,大小都是一样的,都是4个字节或者是8个字节
指针变量类型的意义
指针变量的的大小和类型无关,,那各种各样的指针类型有什么意义呢
指针的解引用
解引用就是通过地址指向对象,而指针类型决定了对指针解引用时访问字节的大小
如果是char*
指针类型,那么指针解引用时就只能访问一个字节,如果是int*
指针,解引用时就能访问四4个字节
指针加整数
如果是char*
指针变量+1,就是跳过了一个字节,如果是int*
的指针+1,就是跳过了4个字节
指针+1,实际上就是跳过了1个指针指向的元素,指针可以加也可以减
void*指针
指针有一个特殊的类型,叫void*
类型,相信大家已经见过void好多次了,void*
可以理解为无具体指针类型的(泛型指针)
这种指针可以用来接受任何类型的地址
但是也有一些局限性,比如void*指针类型不能直接进行指针加减整数和解引用的运算
void*
指针一般使用在函数参数部分,用来接收不同数据类型的数据的地址
小小的总结一下(掺杂强烈的个人看法):个人觉得学到指针就老实了可能是因为它大量的定义以及数据量让很多人望而却步,但是其繁琐的本质依旧是在地址上做文章,所以这一节的内容极为重要,希望家人们可以理解!!!
今天的知识讲解完啦,如果觉得有用可以点一下赞和关注,也可以先收藏以防需要时找不到哦,当然如果作者写的哪里有问题欢迎指出,我们一起进步!!!
祝看到这里的人天天开心哦(笔芯)