结构体指针的强制类型转换在链表的使用中是非常有用的一种方式:

  (比如我们有一条链表(我们知道每一个链表的节点都是一种结构体),而链表中的每一个节点又是某一个结构体中的成员,

我们就可以通过查询链表的节点,通过将节点强制转换为某个结构体,然后我们就可以方便的使用某个结构体的其他成员了)。

     那么结构体之间的强制转换又是基于什么的原理实现的呢?需要明白下面几点:

  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型。

 强制类型转换就是在内存地址上的赋值,如果其强制转换,破坏了结构体的原有结构,则不行