結構體指針的強制類型轉換在鏈表的使用中是非常有用的一種方式:
(比如我們有一條鏈表(我們知道每一個鏈表的節點都是一種結構體),而鏈表中的每一個節點又是某一個結構體中的成員,
我們就可以通過查詢鏈表的節點,通過將節點強制轉換為某個結構體,然后我們就可以方便的使用某個結構體的其他成員了)。
那么結構體之間的強制轉換又是基於什么的原理實現的呢?需要明白下面幾點:
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型。
強制類型轉換就是在內存地址上的賦值,如果其強制轉換,破壞了結構體的原有結構,則不行
