07.09 结构体指针强制转化

hello小伙伴们中午好!今天我们来聊聊结构体指针强制转化!

类型转换也可以根据如下理解:

例如:b->num : 将 struct A a 所指向的内存单元以 struct B b的分布方式(利用 b)取得偏移为num 的值。

结构体成员声明该成员在结构体中的偏移地址。

解释如下:

1、首先要明确struct B b本身有一个值(在32位机上一般是32位),这个值代表着某个内存地址,比如这个首地址值是0x30000000,由于b被定义Struct B类型,那么编译器在编译源文件时就会认为b指向的是一个struct B的结构,这个结构的内容由一段连续的内存存储,(b->num)(b->type)(b->age)在struct B的定义中肯定是存在num、type、age三个的,这几个变量对一个struct B结构的地址偏移量是固定的,也就是说只要知道一个struct B结构的起始地址,就能计算出这个结构所包含的num、type、age的地址,由于B b的地址已知(由A a强制转换而来,所以编译器知道这个地址即a的首地址),b所含的num离b的偏移量已知,那么就能通过b实现对num的取值,在编译器编译C文件的时候并不管b中的nun是否定义

2、b被定义为struct B,而B中又包含b,那么编译器就认为b所指向的结构中存在num

3、b->num如果不发生保护错误,总是能取到一个值(这个值就是对b偏移一定距离的内存单元中的值),只是这个值不能确定是否是你期望的值

4、再次提醒,变量的值是存储在内存中的,每个内存字节对应一个内存地址,而内存存储的值本身是没有整型,指针,字符等的区别的,区别的存在是因为我们对它们有不同的解读,b的值就是一个32位值,并且存储在某个内存单元中,通过这个32位值就能找到b所指向的结构的起始地址,通过这个起始地址和各个结构所包含变量离起始地址的偏移对这些变量进行引用,b->num只是这种引用更易读的写法,只要b是指向num 的指针,那么b的值就肯定存在,b存在,偏移量已知,那么b->num就肯定存在,只是要记住,b->num只是代表了对num一定偏移地址的值

5、假如b->num所对应的这段内存从未有进行过操作,那么其值就是系统上电启动之后的内存的默认值,如果有其他程序使用过,那么其值就是其他程序执行后在这段内存中留下的值,总之,每个正常工作的内存单元中都是有值的,无论这些值是否是我们所需要的,它们始终是存在的。你可以把内存想象成一个大数组,当你在程序中定义了一个数组,但是并没有初始化,但是你也可以引用数组元素,只是引用的值是未知的,道理是类似的

2、将int强制类型转换为结构体类型

typedef struct eg

{

int x;

int y;

}eg;

int point = 0x30000000;

eg peg = (eg)point;

可以看到point本身只是个整型变量,但是这样的赋值是合法的,peg->x的值是0x30000000开始的四字节,peg->y是0x30000004开始的四字节。

解释如下:

不是说某个地址有那个结构体你才能引用,即使没有,你也能引用,因为你已经告诉了编译器param变量就是指向一个PAINT_PARAM结构体的变量并且指明了param的值,机器码的眼中是没有数据结构一说的,它只是机械的按照指令的要求从内存地址取值,那刚才的例子来说,peg->x,peg->y的引用无论0x30000000是否存在一个eg结构体都是合法的,如果0x30000000开始的8个字节存在eg结构体,那么引用的就是这个结构体的值,如果这个位置是未定义的值,那么引用的结果就是这8个字节中的未定义值,内存位置总是存在的,而对内存中值的引用就是从这些内存位置对应的内存单元取值。

好啦,今天的有关内容奉送完毕!更多精彩内容详细关注百战程序员哦!另外,大家喜欢这篇文章可不可以点击文章上方的关注呀!小编会为大家提供更多实用的文章哦!