结构体指针的强制类型转换在链表的使用中是非常有用的一种方式:
(比如我们有一条链表(我们知道每一个链表的节点都是一种结构体),而链表中的每一个节点又是某一个结构体中的成员,
我们就可以通过查询链表的节点,通过将节点强制转换为某个结构体,然后我们就可以方便的使用某个结构体的其他成员了)。
那么结构体之间的强制转换又是基于什么的原理实现的呢?需要明白下面几点:
1、结构体声明如何内存的分布,
2、结构体指针声明结构体的首地址,
3、结构体成员声明该成员在结构体中的偏移地址
举个例子:
typedef struct _General_Node
{
//无论任何结点一定包含虚线内的部分
//--------------------------------
DoubleNode node; //结点
S32 Nodetype; //结点类型 不同类型的结点对应不同的处理方法
S32 subType; //结点子类型(多种灵活用途)
U32 NodeFlag; //标志
PDoubleNode pNode; //本结点指向的上\下层段中的结点
PDoubleList pList; //本结点指向的上\下层段指针
S32 Pid; //参数ID
S32 Caption; //标题ID
// PTOUCHAREA Touch; //结点的触摸区指针
WNDPROC DrawFunc; //绘制程序
WNDPROC ProcFunc; //焦点处理程序
//--------------------------------
}GENERALNODE, *PGENERALNODE;
这是一个大的结构体其中的DoubleNode node是一个链表中的节点定义为:
typedef struct _DoubleNode {
U32 ID; //结点的ID 每一个结点有它唯一的ID
struct _DoubleNode *next;
struct _DoubleNode *previous;
} DoubleNode, *PDoubleNode;
这两个结构体他们的首地址是一样的,且struct_DoubleNode为struct _General_Node子关系;
我们知道没一种类型在内存所占的空间是不一样的,比如int型在内存的读取方式为从首地址开始读取32位的数据。
而类型转换可以理解为首地址不变,我们把其读取方式改变。
上面的两个结构体,他们的首地址的一样,其第一个偏移也是一样所以可以进行强制类型转换()。
结构体之间和结构体指针之间的转换略有不同,其很重要的一点就是字节对齐方式。
例如:struct A struct B
{ {
char a; int c;
int b; char d;
} ; };
上面两个结构体式可以进行强制转换的,因为他们的对齐方式是一样的。他们之间的转换就好比char型转换为int型,int型转换为char型。
强制类型转换就是在内存地址上的赋值,如果其强制转换,破坏了结构体的原有结构,则不行