有如下结构体定义: typedef struct cemsg { uchar dl; uchar mg; uchar data[10]; }CEMSG; typedef struct msg{ uchar id; uchar cmd; uchar byte[4]; }MSG; typedef struct msg_p{ uchar id; uchar cmd; uchar far * ptr; }MSG_P; void ap_getmsg(MSG *d_OsMsgPtr,CEMSG *d_CeMsgPtr) { MSG_P *d_p; d_p = ( MSG_P * )d_OsMsgPtr; cpy( d_CeMsgPtr, d_p->ptr, ( ushort )(( CEMSG far* )d_p->ptr )->dl + 1 ); } 注:其中cpy(dest,src,n)函数的功能是把src开始的n byte数据copy到dest开始的数据区域内。 在仿真调试中: 程序进入函数时,d_OsMsgPtr的个数据项地址及值如下: 地址d_OsMsgPtr---0x00ffb21c ; d_OsMsgPtr->byte[4]---0x00ffb21e 值d_OsMsgPtr->id==0x0c;d_OsMsgPtr->cmd == 0x11; d_OsMsgPtr->byte[0]==0xD4;d_OsMsgPtr->byte[1]==0xD0;d_OsMsgPtr->byte[2]==0xFF;d_OsMsgPtr->byte[3]==0x00; 当函数执行完d_p = ( MSG_P * )d_OsMsgPtr;这句时: 地址d_p---0x00ffb21c ; d_p->ptr---0x00ffD0D4 值d_p->id==0x0c;d_p->cmd == 0x11; *d_p->ptr==0x06; /********************************************************************************************************************************************/ 请问: 1:在对d_OsMsgPtr强制转换为MSG_P类型时,具体的执行过程时怎样的,为什么转换之后,d_p的地址为d_OsMsgPtr的0x00ffb21c,d_p->ptr的地址却不是d_OsMsgPtr- >byte[4]的地址。 2:转换完毕之后,d_p->ptr应该是指向d_OsMsgPtr->byte的指针,但是为什么*d_p->ptr的值不是d_OsMsgPtr->byte[0],0x06又是从何而来呢? 3:( CEMSG far* )d_p->ptr 这句,CEMSG是一个结构体类型,d_p->ptr是一个指向一个数组的指针类型,并且是一个结构体的数据项,这样的类型转换,又是如何操作的呢? 4:0x06是不是结构体msg_p的长度呢?存放在地址0x00ffD0D4中? 答:1、指针强制类型转换实际上是用新的指针类型来解析原来地址空间中的内容 比如d_OsMsgPtr原来空间的内容是 (struct msg_p) 1byte 1byte 4bytes id cmd byte[4] 强制类型转换之后,要以struct msg_p来解析该内容 一共6bytes 1byte 1byte 4bytes id cmd ptr 原来byte[4]的内容成为ptr的内容,而不是byte[4]的首地址. *****注意强制转换后,是用新的结构体来解析原来空间的内容 所以强制转换后的结构体内的指针把原来空间的内容当作自己的内容,而不是指向原来空间的地址 所以&(d_p->ptr)才是d_OsMsgPtr->byte的首地址 同样在进行( CEMSG far* )d_p->ptr 转换后 &(d_p->ptr)才是uchar data[10];的首地址 而且有一个问题,结构体的长度不一致,进行强制类型转换后,可能出现内存访问越界 2、由于d_p->ptr内存放的值是0x00ffD0D4,所以 *d_p->ptr的值实际上是内存中(0x00ffD0D4)单元中存放的内容 3、首先d_p->ptr 所指向的地址并不是你预想中所指的地址,所以对它进行强制类型转换,结果未知.(是不安全的) 4、与结构体长度无关,实际上,你幸好没有做*d_p->ptr = ***(赋值)操作 否则,将对0x00ffD0D4地址的内容进行操作,这并不是合法的操作.