C 小技巧之CONTAINING RECORD

2022-04-30 13:12:10 字數 1288 閱讀 1256

containing record是乙個在c++程式設計中用處很大的一種技巧,它的功能為已知結構體或類的某一成員物件中該成員的位址以及這一結構體名或類名,從而得到該物件的基位址

由於寫法簡單,它被當做乙個巨集來使用,寫法是這樣的。

#define containing_record(address,type,field) \

((type*)((pchar)(address)-(ulong_ptr)(&((type*)0)->field)))

用type*來對0進行強制型別轉換(type是乙個結構體名或類名)再呼叫其成員後,該成員的位址就等於其相對於基位址的相對位址即偏移。

typedef struct data,*pdata;

int main()

明白了這個就更容易理解containing_record的實現了,顯然,該物件的絕對位址,就等於物件中某乙個成員的絕對位址減去這一成員的相對位址。而剛剛我們計算的就是這一相對位址。(ulong_ptr)(&((type*)0)->field))

(pchar)(address)則是該成員的絕對位址,最後兩個相減,就得到了物件的基位址,利用這個基位址可以做很多事情。

注意取位址之後的強制型別轉換

最終的實現:

typedef struct data,*pdata;

// 利用位址的偏移和對0用結構體指標型強制型別轉換來實現對結構體基位址的定址。

#define containing_record(address,type,field) ((type*)((pchar)(address)-(ulong_ptr)(&((type*)0)->field)))

int main()

; //int* v3 = (int*)(&((pdata)0)->m_1);

int* v1 = &data.m_2;

pdata v2 = containing_record(v1, data, m_2);

printf("%d %d %d\n", v2->m_1,v2->m_2,v2->m_3);

//printf("%p\r\n", v3);

return 0;

}//最終v2就是物件data的位址,我們可以不使用data就直接訪問該物件的成員

C 小技巧之貪婪匹配

相信很多c c 初學者在教科書或者考試中遇到過這樣的問題,下面的 輸出值為多少 很多人都很迷惑,三個加號在一起,到底是 a b呢還是a b 呢?我當時也很迷惑,自己寫程式執行一遍,發現,a 1 b 1。這才知道是 a b,可沒幾天就忘了。我記性不好。最近看了看herb sutter的exceptio...

C 開發小技巧之筆記

一 vc2008如何將lib檔案引入 lib引用有兩種方法 1.pragma comment lib,opengl32.lib 2.選擇project xx properties.linker input additional dependences,在其中加入lib檔名即可。注意要放到工程目錄下。...

zmud之小技巧

1.自動enforce和enchant最大值 由enable激發trigger tri 由hp激發trigger tri tri func maxlevel 獲得最大能學習的skill的乙個好處是可以在學習機器中自動判斷最大值,不管是法術還是普通技能都由這個 max sk來限制,從而方便平均技能級別...