简单记录一下这段时间学习指针的知识点与个人需要注意的地方,后续会把不对的地方改改
1 地址与指针
存放变量到内存里面的时候,都是由一组有序的字节组成的地址来进行存储,每个字节都有相对于的内存地址。
地址 字节
如果将内存看成房间,那么存放的字节就是房间里的物品,地址就是门牌号,通过门牌号可以快速找到房间来存放或者取出物品。
相应的,计算机可以通过地址快速找到存放相应字节的内存。而指针,则是记录了门牌号的地图,可以带我们找到我们想要的内存地址。
可以看到,存放了数组a[]地址的指针p是和a[]打印相同的,可以简单理解:内存单元的编号 == 地址 == 指针
指针相比于直接引用地址,使用限制更少更加灵活,使得我们在编写代码时候可以更高效、紧凑。
2.指针变量与地址
2.1 取地址
上面图可以看到,数组a[]的地址有很多,我们要怎么取单一的字节地址?
这时候就用到取地址符“&” 了
&a取出的是a[]所占字节中地址较小的数组的第一个地址。如果要取第i个数组所在的地址,用&a[i]就能取出。我们只要知道了第⼀个字节地址,顺藤摸瓜访问到4个字节的数据也是可行的。
2.2指针变量
那我们通过取地址操作符(&)拿到的地址是⼀个数值,比如:0x0000006FE7AFF4B8,这个数值有时候也是需要 存储起来,方便后期再使用的,那我们把这样的地址值存放在哪里呢?答案是:指针变量中。
指针变量也是⼀种变量,这种变量就是用来存放地址的,存放在指针变量中的值都会理解为地址。
2.3.1指针类型
我们可以看到,指针pa的类型是int*,*是说明pa是指针变量,int说明pa是指向整数(int)类型的对象。
相应的,不同的指针变量类型指向不同的对象,不能串用。
2.3.2解引用操作符
我们将地址保存在指针里面,那我们要使用的时候就要使用到解引用操作符(*)了
可以看到,*pa的意思就是通过pa存放的地址找到对应的空间再改变相应的变量,在这*pa=9相对于把a=10改成了a=9。
这里是把a的修改交给了pa来操作,这样对a的修改,就多了⼀种的途径,写代码就会更加灵活。
2.3.3指针变量大小
这里偷个懒,简单记一下结论。
32位平台下地址是32个bit位,指针变量大小是4个字节。
•64位平台下地址是64个bit位,指针变量大小是8个字节。
注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。
3指针变量类型的意义
指针变量的大小和类型无关,只要是指针变量,在同⼀个平台下,大小都是⼀样的。但是有特殊的地方。
3.1再=在解引用上的区别
直接记结论
指针的类型决定了对指针解引用的时候有多大的权限(⼀次能操作几个字节)。
例如:char*一次只能解引用一个字节,int*形可以一次性解引用四个字节。
3.2void*指针
void*是一种特殊的指针(无具体类型的指针),可以接受任意类型的地址。
不过也有局限,那就是不能直接进行指针+-整数和解引用运算。
将int型变量地址赋给char型指针,运行时候编译器报了警告,就是因为类型不兼容。而void*就把不会出现这种情况。(偷个懒,感兴趣的小伙伴可以回自己的编译器试一下)
再来看看void的解引用运算
看到void*类型的指针可以接收不同类型的地址,但是无法直接进⾏指针运算。
void*的用法放在后面再讲吧。
3.3指针+-整数
可以看到, char+1和int+1跳过的字节是不一样的,char跳过1字节,int跳过4字节,这也是不同类型的权限的不同。
结论:指针的类型决定了指针向前或者向后跳过的字节有多大。