一、指针的概念:
要知道指针的概念,要先了解变量在内存中如何存储的。在存储时,内存被分为一块一块的。每一块都有一个特有的编号。而这个编号可以暂时理解为指针,就像酒店的门牌号一样。
1. 内存和地址
1.1 内存
在讲内存和地址之前,我们想有个⽣活中的案例: 假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩, 如果想找到你,就得挨个房⼦去找,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给每个房间编上号,如:
有了房间号就可以快速准确的找到房间,那么放在放在计算机上是怎样的呢?
我们知道计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的 数据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那这些内存空间如何 ⾼效的管理呢? 其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。每个内存单元相当于一个宿舍,里面住着八个同学(八个比特位)。每个宿舍都有编号,每个内存单元也有“编号”——地址。在我们C语言中也叫指针,即 编号=地址=C语言中指针。
1.2 地址
那么如何理解地址呢?CPU访问内存中的某个字节空间,必须知道这个字节空间在内存的什么位置,⽽因为内存中字节很多,所以需要给内存进⾏编址,就如同宿舍很多,需要给宿舍编号⼀样。 计算机中的编址,并不是把每个字节的地址记录下来,⽽是通过硬件设计完成的。
计算机中有许多硬件单元,这些硬件单元靠“线”进行连接——地址总线。我们可以简单理解,32位机器有32根地址总线, 每根线只有两态,表⽰0,1【电脉冲有⽆】,共有2^32种由0和1组成的32位数,每⼀个都代表⼀个地址。
2. 指针变量和解引⽤操作符(*)
2.1 指针变量
我们通过取地址操作符(&)拿到的地址是⼀个数值,⽐如:0x006FFD70,这个数值有时候也是需要 存储起来,⽅便后期再使⽤的,我们把这样的地址值存放在指针变量中。
需要注意的是指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。
我们看到pa的类型是 int* ,我们该如何理解指针的类型呢?这⾥pa左边写的是 int* , * 是在说明pa是指针变量,⽽前⾯的 int 是在说明pa指向的是整型(int) 类型的对象。那如果有⼀个char类型的变量ch,ch的地址,要放在什么类型的指针变量中呢?
char ch = 'w';
pc = &ch;
2.2 解引用符
我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针) 指向的对象。上⾯代码中*p=0就使⽤了解引⽤操作符, *pa 的意思就是通过pa中存放的地址,找到指向的空间, *pa其实就是a变量了;所以*pa = 0,这个操作符是把a改成了0。
2.3 指针的大小
我们知道指针是存储地址的,地址有多大呢,这与计算机有关如果是32位机器,地址就是32位,64位机器地址就是64位。以32位为例,地址占32个比特位,即4个字节
!注意指针变量的⼤⼩和类型是⽆关的,在相同的平台下指针类型的变量⼤⼩都是相同的。
3. const 修饰指针
⼀般来讲const修饰指针变量,可以放在*的左边,也可以放在*的右边,意义是不⼀样的。
4.指针运算
指针的基本运算有三种,分别是:
• 指针+- 整数
• 指针-指针
• 指针的关系运算
4.1 指针+- 整数
因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺藤摸⽠就能找到后⾯的所有元素。
4.2 指针-指针
4.3 指针的关系运算
5、野指针
概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
5.1 出现原因
1.指针未初始化
2.指针越界访问
3.指针指向的空间释放
5.2 如何规避
1.指针初始化
2. ⼩⼼指针越界
⼀个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是 越界访问。
3. 指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性
4.避免返回局部变量
好了,关于指针的知识先分享到这里,后面部分请期待后续!