区分指针加一和普通类型(如int 、char、double)加一
指针加一:指针加一包括普通指针(如int *...)、数组指针、结构体指针等等,对指针进行加1操作,得到的将是下一个元素的地址,一个类型为T(如int (*) [5]的数组指针类型)的指针移动,是以sizeof(T)为移动单位。
普通变量加一:普通变量加一其实就是数学上的加一操作。地址如果转换成普通变量,需要注意该普通变量的类型的数值范围是否可以容纳下地址的数值大小而不发生数值丢失。
需要注意的是,当你把地址前置装换成char类型是会出错的,是因为char类型的内存空间(1字节)有限,也就是他的值得范围是有限的,所以你把地址前置转换成char后再转成int *类型(或者其他指针类型)去解析,很有可能会出现段错误(应该是一定会出现段错误,因为对应char的数值范围大小的内存区间是kernel用的地址空间,拒绝访问)。
总结:指针移动的目的就是为了去访问内存地址。而内存地址抽象出来的就是数字,我们进行指针访问时,需要移动指针其实就是对内存地址的数值进行加减运算,使得我们的指针指向我们想要访问数据的内存空间的头位置处,然后在通过强制类型转换(如果类型匹配,也可以不用强制类型转换),用我们想要的解析方法去读取该内存空间的数。
代码演示:
#include<stdio.h> typedef struct test { int a; double b; char c; }Test; int main(void) { Test chen; chen.a = 5; chen.b = 19; chen.c = \'a\'; //double *p1 = (double *)((char)&chen + 4);//这种强制类型转换导致&chen的数值丢失了 double *p2 = (double *)((int)&chen + 4); //把&chen转为普通的数值,需要+4后才指向下 //一个结构体元素,chen.b double *p3 = (double *)((char *)&chen + 4);//把&chen转为char 类型的指针,加1,表示移 //动sizeof(char)个单位,所以要移
//动4个单位才可以指向chen.b double *p4 = (double *)((int *)&chen + 1); //把&chen转为int 类型的指针,加1,表示
//移动sizeof(int)个单位,所以只需要移
//动1个单位就可以指向chen.b //printf("*p1 = %f.\n", *p1); //去访问了不能访问的地址空间,会发生段错误 printf("*p2 = %f.\n", *p2); printf("*p3 = %f.\n", *p3); printf("*p4 = %f.\n", *p4); return 0; }
打印的结果:
觉得对你有所帮助,请点赞!如果觉得有什么不懂也请留言询问,我会及时回复的!