考考你 根據結構體變數位址反推結構體首位址

2022-02-12 03:40:49 字數 1642 閱讀 7951

考考你:根據結構體變數位址反推結構體首位址

2011-07-21 16:51:38

標籤:結構體

首位址container_of

offsetof

偏移最近在看《linux核心設計與實現》這本書,感覺寫得非常棒,看第6章《核心資料結構》的時候,遇到兩個非常牛b的巨集,據此簡單地設計乙個考題,以便分析它們。

【題目】:

根據乙個結構體某成員的名稱和位址,以及結構體的型別,計算出該結構體物件的首位址。

【例如】:

struct

a   

#define get_header_addr(member_name,member_addr,struct_type) (你來實現) 

void

main()   

不看下面的答案,你來嘗試實現上面這個巨集吧。

【答案與分析過程】

linux核心中,用兩個非常巧妙地巨集實現了,乙個是offsetof巨集,另乙個是container_of巨集,下面講解一下這兩個巨集。

1.  offsetof巨集

【定義】:#define offsetof(type, member) ((size_t) & ((type *)0)->member )

【功能】: 獲得乙個結構體變數成員在此結構體中的偏移量。

【例子】: 

struct

a ; 

void

main() 

// 輸出結果為 8

【分析】:

該巨集,type為結構體型別,member 為結構體內的變數名。

(type *)0) 是欺騙編譯器說有乙個指向結構type 的指標,其位址值0 

(type *)0)->member 是要取得結構體type中成員變數member的位址. 因為基址為0,所以,這時member的位址當然就是member在type中的偏移了。

2. container_of巨集(即實現了題目中的功能

【定義】:

#define container_of(ptr, type, member)   ()

【功能】:

從結構體(type)某成員變數(member)指標(ptr)來求出該結構體(type)的首指標。

【例子】:

struct

a ; 

struct

a mytest; 

int*pz = &mytest.z; 

struct

a* getheaderptr( 

int*pz ) 

【分析】:

(1) typeof( ( (type *)0)->member )為取出member成員的變數型別。

(2) 定義__mptr指標ptr為指向該成員變數的指標(即指向ptr所指向的變數處)

(3) (char *)__mptr - offsetof(type,member)) 用該成員變數的實際位址減去該變數在結構體中的偏移,來求出結構體起始位址。

(4) ()這個擴充套件返回程式塊中最後乙個表示式的值。

本文出自 「對影成三人」 部落格,請務必保留此出處

ORACLE題目考考你

1,現有乙個公司的部門及雇員的資料庫,由下面三個表組成 a 雇員 雇員號,姓名,年齡,位址,薪水 b 部門 部門號,部門名,部門經理號 c 工作 雇員號,部門號,工作年限 用pl sql語句查詢和其部門經理住址相同的員工的姓名及經理姓名?color blue 雇員 create table empl...

考考你乙個WPF布局

要建立如圖一樣布局,請問怎麼實現?其實考題本身沒有任何實用價值,只是一種思維的拓展。看似用dockpanel實現,那麼就錯了,因為top button沒有佔據top的全部。實際上是用了很簡單grid實現,如果你能用其他方式實現,歡迎跟帖。code window x class griddemo.co...

考考你的邏輯推理能力

自以為自己作為一名程式猿,邏輯推理能力會不錯,不過昨天在一本叫做 你以為你以為的就是你以為的嗎 書裡做了四道測試題,大敗啊。現在把四道題給大家公布出來,考考各位程式設計師的邏輯思維能力。一 偶數與母音。二 有色的圓圈和正方形 三 狡猾的飲酒者 四 工作時間上網衝浪 總結 如果一種信念是建立在不完善的...