offsetof與container_of宏的理解

這兩個是在linux內(nèi)核中經(jīng)常用到的兩個宏,先說offsetof這個宏的作用就是來計算在結(jié)構(gòu)體中的一個元素與結(jié)構(gòu)體地址的偏移量。結(jié)構(gòu)體的元素訪問其實就是指針訪問,直接應(yīng)用的時候是用一個點來訪問的但是其實在底層經(jīng)過編譯器編譯后的執(zhí)行程序還是用這個偏移量的地址來訪問的例如定義一個結(jié)構(gòu)體如下
typedef struct test{
char t1;
int t2;
short t3;
}test;
int main(void)
{
test s1;
s1.t1='a';
s1.t2=123;
s1.t3=456;

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、小程序制作、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了阿圖什免費建站歡迎大家使用!

return 0;

}
這種用點的形式直接訪問其本質(zhì)是如下的:

test p;
char
p1;
int p2;
short
p3;
p=&s1;
p1=(char )((int)p+0)
p2=(int
)((int)p + 4);
p3=(short *)((int)p + 8);

printf("*p1 = %c.\n",*p1);
printf("*p2 = %d.\n",*p2);
printf("*p3 = %d.\n",*p3);
這樣得到結(jié)構(gòu)是完全正確的意思就是這個偏移量很重要,所有就產(chǎn)生了offsetof這個宏,他的原型是
#define offsetof(Type,Member)  ((int)&((Type*)0)->Member)
首先有兩個參數(shù)Type是指這個結(jié)構(gòu)體的類型名,member就是這個結(jié)構(gòu)體的成員名經(jīng)過這個宏之后就返回了一個×××數(shù)是這個成員變量在這個結(jié)構(gòu)體中相對于結(jié)構(gòu)體地址的偏移量這里邊有一個(Type*)0)最不好理解意思就是假設(shè)了一個type類型的結(jié)構(gòu)體他的地址是在地址0處其實這個結(jié)構(gòu)體是不存在的但是這樣假定使用是不會有問題的,因你又沒有引用這個地址所有就沒有問題了,其實返回的這個數(shù)就是這個成員的地址減去結(jié)構(gòu)體的地址但是因為結(jié)構(gòu)體的地址是0所有就能直接返回這個成員的地址而也正因為結(jié)構(gòu)體的地址是零所有成員的地址也就正好是偏移量了。
而container_of這個宏就是在offsetof這個宏的基礎(chǔ)上發(fā)展來的他的作用就是知道一個結(jié)構(gòu)體中的成員的地址通過這個宏的運算后得到了結(jié)構(gòu)體的地址,這個就厲害了因為你只要知道了結(jié)構(gòu)體的指針那么你就可以得到結(jié)構(gòu)體中的任何一個元素。這個宏的源型是#define container_of(ptr,type,member)  ({\

Const typeof(((type)0)->member) mptr = (ptr);\
(type)((char)
mptr - offsetof(type,member));})

有三個參數(shù)ptr是結(jié)構(gòu)體中元素的指針,type是結(jié)構(gòu)體的類型名,member是這個ptr指針的結(jié)構(gòu)體元素名。這個宏里第一條我覺得其實也沒什么用去掉應(yīng)該也可以因為他只是得到了這個結(jié)構(gòu)體中成員變量的類型,之后這個成員變量的地址減去他在結(jié)構(gòu)體中的偏移量那得到的就是結(jié)構(gòu)體的指針在將類型強制轉(zhuǎn)換為結(jié)構(gòu)體指針就可以了。

網(wǎng)頁題目:offsetof與container_of宏的理解
標題網(wǎng)址:http://muchs.cn/article18/ppjhdp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、手機網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)站維護、標簽優(yōu)化網(wǎng)站設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)