1、内存和地址
1.1内存
在生活中相当于一栋楼中房间号,在计算机中cpu,在处理数据时,需要的数据就是在内存中读取的,处理以后的数据也会放在内存中,内存会被划分成一个一个的内存单元,每个内存单元的大小取一个字节
一个比特位可以存储一个2进制的为1或0;
bit——比特位;Byte——字节;
1Byte=8bit;1kB=1024Byte;1MB=1024kB
其中,每个内存单元,相当于一个学生宿舍,一个字节空间里面能放8个比特位,每个内存单元也都有一个编号,我们可以理解为内存单元的编号==地址==指针
1.2理解编址
32位机器上有32根地址总线,每根线上只有两态,表示0,1,那么一根线就能表示两种含义,32根地址线就能表示2^32种含义,每种含义都表示一个地址,地址信息被下达给内存,在内存上就可以1找到该地址对应的数据,将数据在通过数据总线传入cpu内寄存器;计算机是有很多硬件单元的,硬件单元是要相互协同工作的,所谓的协同,至少相互之间要能够进行数据传递;通过“线”连接起来
控制总线传递的信息是是读还是写,如果读,首先从地址线上传输一个信号,告诉cpu要读取一个数据,地址信号通过地址线传输过去,通过地址信号找到内存单元,通过数据总线,再将数据传输过去
2、指针变量和地址
2.1取地址操作符
变量创建的本质是在内存中开辟了一块空间
25的四个字节每个字节都有自己对应的地址,那么当取地址时是拿的那个地址呢
拿的是第一个字节的地址,当知道第一个字节的地址,顺藤摸瓜,就会知道后面字节的地址
2.2指针变量和解引用操作符(*)
2.2.1指针变量
###
p是指针变量——存放地址的变量;int是在说明p指向的对象是int类型的,*是在说明p是指针变量;
因此存放char类型的指针,要用char类型的指针
2.2.2解引用操作符
###
*——解引用操作符(间接访问操作符),*p等价于a
2.3指针变量的大小
* 在32位机器上,地址是32个二进制序列,存储起来需要32个比特位,也就是4个字节,指针变量的大小就是4个字节
* 在64位机器上,地址是64个二进制序列,存储起来需要64个比特位,也就是8个字节,指针变量的大小就是8个字节
*指针变量的大小和类型是无关的,只要是指针类型的变量,在同一个平台下,大小都是一样的
3.指针类型变量的意义
3.1指针的解引用
## 调试可以看到,第一个会将四个字节全部改为0,第二个只将第一个字节改为0;
指针类型决定了,对指针解引用的最大权限,如int*的指针解引用能访问四个字节,char*指针解引用只能访问一个字节
3.2指针加减整数
可以看出char*类型的指针变量+1跳过一个字节,int*类型的指针+1跳过了四个字节
指针的类型决定了指针向前或者向后走一步有多大
3.3void*指针
可以理解为无具体类型的指针(泛型指针),这种类型的指针可以用来接受任意类型的地址,但是不能进行指针的+-整数和解引用操作
4.const修饰指针
变量是可以修改的,但是被const修饰后,在语法上加上了限制
如代码中对n进行修改,就不符合语法规则,报错
但是可以通过n的地址,修改n
可以看到确实被修改了,如过想要p拿到n的地址也不能修改,就应该用const修饰指针变量
4.1const修饰指针变量
测试const放在*的左边的情况
测试const放在*右边的情况
测试*左右两边都有const的情况
###
*const如果放在*的左边,修饰的是指针指向的zh内容,保证指针指向的内容不能通过指针来改变,但是指针变量本身的内容可变
*const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变
5.指针运算
5.1指针加减整数
5.2指针减指针
指针减指针的绝对值是指针和指针之间的元素个数(运算的前提条件两个指针指向同一片空间)
5.3指针的关系运算
两个指针是可以比较大小的,例如数组地址是从低到高的;
6.野指针
野指针就是指针指向的位置是不可知的(随机,不正确的)
6.1野指针的成因
6.1.1指针未初始化
6.1.2指针越界访问
6.1.3指针指向的空间释放
6.2.4如何规避野指针
指针初始化
小心指针越界
指针变量不再使用时,及时置NULL,指针使用之前检查有效性
避免返回局部变量的地址
7.指针的使用和传值调用
例如:写一个函数,交换两个整型变量的值,可能会写出如下代码:
没有发现交换的效果,这是为什么呢?
实参传递给形参的时候,形参会单独创建一份临时空间来接受实参,对形参的修改不影响实参
这个时候指针就派上用场了,通过交换函数里面地址间接操作,达到交换效果
将变量的指针传递给了函数1,这种函数调用方式叫:传址调用;
传址调⽤,可以让函数和主调函数之间建⽴真正的联系,在函数内部可以修改主调函数中的变量;所 以未来函数中只是需要主调函数中的变量值,就可以采⽤传值调⽤。如果函数内部要修改 主调函数中的变量的值,就需要传址调⽤。
标签:const,字节,地址,理解,深入,内存,指针,变量 From: https://blog.csdn.net/2402_82475148/article/details/136638845