用一個宏定義FIND求一個結構體struct裡某個變數相對struc的編移量

來源:互聯網
上載者:User

用一個宏定義FIND求一個結構體struct裡某個變數相對struc的編移量.

如:stuct student
{
int a;
char b[20];
double ccc;
}
則:
FIND(student,a); //等於0
FIND(student,b);//等於4

#define FIND( struc, e ) (size_t)&(((struc*)0)- >e)

(struc*)0----------表示將常量0強制轉化為struc *型指標所指向的地址
&(((struc*)0)- >e)--表示取結構體指標(struc*)0的成員e的地址,因為該結構體的首地址為0,所以其實就是得到了成員e距離結構體首地址的位移量.

(size_t)-----------是一種資料類型,為了便於不同系統之間移植而定義的一種無符號型資料,一般為unsigned int

(struc*)0 表示假設在0地址處有一個結構體struc
((struc*)0)- >e 表示在0地址處的結構體struc的成員e
&(((struc*)0)- >e) 表示在0地址處的結構體struc的成員e 的地址
(size_t)&(((struc*)0)- >e) 將0地址處的結構體struc的成員e 的地址轉換成整數類型

 

 

#define OFFSETOF(type, field) ((size_t)&(((type *)0)->field))

(type *)0:把0地址當成type類型的指標。

((type *)0)->field:對應域的變數。

&((type *)0)->field:取該變數的地址,其實就等於該域相對於0地址的位移量。

(size_t)&(((type *)0)->field):將該地址(位移量)轉化為size_t型資料。

ANSI C標準允許任何值為0的常量被強制轉換成任何一種類型的指標,並且轉換結果是一個NULL指標,因此((s*)0)的結果就是一個類型為s*的NULL指 針。如果利用這個NULL指標來訪問s的成員當然是非法的,但&(((s*)0)->m)的意圖並非想存取s欄位內容,而僅僅是計算當結構 體執行個體的首址為((s*)0)時m欄位的地址。聰明的編譯器根本就不產生訪問m的代碼,而僅僅是根據s的記憶體布局和結構體執行個體首址在編譯期計算這個(常 量)地址,這樣就完全避免了通過NULL指標訪問記憶體的問題。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.