指针是C语言中的一个难点,但如果真正理解了指针,其实没有很难,本篇文章介绍了指针的基础知识,后面还会继续更行指针的内容。感谢支持。
目录
1. 内存和地址
1.1 内存
1.2 究竟该如何理解编址
2. 指针变量和地址
2.1 取地址操作符(&)
2.2 指针变量和解引⽤操作符(*)
2.2.1 指针变量
2.2.2 如何拆解指针类型
2.2.3 解引⽤操作符
2.3 指针变量的⼤⼩
3. 指针变量类型的意义
3.1 指针的解引⽤
3.2 指针+-整数
3.3 void* 指针
4. const修饰指针
4.1 const修饰变量
4.2 const修饰指针变量
5. 指针运算
5.1 指针+- 整数
5.2 指针-指针
5.3 指针的关系运算
1. 内存和地址
1.1 内存
CPU( 中央处理器) 在处理数据的时候 ,需要的数据是在内存中读取的 ,处理后的数 据也会放回内存中 ,那我们买电脑的时候 , 电脑上内存是8GB/16GB/32GB等 。内存划分为一个个的内存单元 ,每个内存单元的大小取1个字节,方便高效管理。
计算机中常见的单位:
其实每个内存单元都有自己的唯一确定的编号,通过这个编号,CPU就可以快速,找到对应的内存空间,这个编号也就是地址,在C语言中也有一个名字叫作:地址。
我们可以理解为:内存单元的编号==地址==指针
1.2 究竟该如何理解编址
CPU访问内存中的某个字节空间 ,必须知道这个 字节空间在内存的什么位置 ,而因为内存中字节很多 ,所以需要给内存进行编址(就如同宿舍很多 ,需要给宿舍编号一样)。
计算机中的编址 ,并不是把每个字节的地址记录 下来 ,而是通过硬件设计完成的。
首先 ,必须理解 ,计算机内是有很多硬件单元,而硬件单元是要互相协同工作的。所谓的协同 ,至少相互之间要能够进行数据传递。
但是硬件与硬件之间是互相独立的 ,那么如何通信呢?答案很简单 ,用"线"连起来。
而CPU和内存之间也是有大量的数据交互的 ,所以 ,两者必须也用线连起来。
不过 ,我们今天关心一组线 ,叫做地址总线。
我们可以简单理解,32位机器有32根地址总线,每根线只有两态 ,表示0或1【电脉冲有无】 ,那么一根线 ,就能表示2种含义 ,2根线就能表示4种含 义 ,依次类推。32根地址线 ,就能表示2^32种含 义 ,每一种含义都代表一个地址。
地址信息被下达给内存 ,在内存上 ,就可以找到该地址对应的数据 ,将数据在通过数据总线传入 CPU内寄存器。
2. 指针变量和地址
2.1 取地址操作符(&)
我们知道C语言中一个整形占4个字节,创建时会向内存申请4字节的空间,当取整形变量的地址时会取出4个字节地址的第一个地址,因为知道是int类型,当需要这个变量时就能顺藤摸瓜,将这4个字节全部访问。
2.2 指针变量和解引⽤操作符(*)
2.2.1 指针变量
在这里p就是指针变量,int*是指针变量类型,p变量里存放的是变量a的地址。
2.2.2 如何拆解指针类型
其实int* p理解为:int是p指针变量所指向的变量的类型。
*理解为:告诉我们p是指针变量。
p理解为:指针变量的名字。
如果是char类型的数据:
2.2.3 解引⽤操作符
我们得到了一个变量的地址,将他存在了一个指针变量中,我们这样做有什么用呢?
我们可以通过地址找到这个地址所指向的变量。来操作,改变它。我们必须要用到解引用操作符:*。
*pa=0;相当于通过pa中存放的地址找到了这个a变量,并把a赋值为0;
我们因为可以看到打印a与打印*pa的结果是一样的。
2.3 指针变量的⼤⼩
我们可以分别看一下在X86(32位)和X64(64位)下打印地址大小的结果:
32位下的结果:
64位下的结果:
可以看到在同一环境下不同类型的地址所占内存的大小是相同的,也就是说地址无贵贱,所占内存大小都遵循下面的规律:
3. 指针变量类型的意义
3.1 指针的解引⽤
代码一:
代码二:
代码一是将int*类型强制类型转变成了char*类型,解引用时只访问了一个字节将44变成了00
而代码二int*类型的pi解引用访问了四个字节,将n全变为0;