chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳細(xì)聊聊container_of這個(gè)宏定義

lilihe92 ? 來(lái)源:最后一個(gè)bug ? 2023-11-13 09:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

正文

大家周末好,我是bug菌~ 今天主要是跟大家詳細(xì)聊聊container_of這個(gè)宏定義,非常經(jīng)典的宏,只是一直沒(méi)有抽時(shí)間細(xì)細(xì)品味,今天就跟大家一起來(lái)看看有何神奇之處:

1offsetof

首先我們需要簡(jiǎn)單看看offsetof(TYPE, MEMBER) 這個(gè)宏定義,它是用于計(jì)算一個(gè)結(jié)構(gòu)體中某個(gè)成員的偏移量。

其第一個(gè)參數(shù) TYPE 是一個(gè)結(jié)構(gòu)體類(lèi)型,第二個(gè)參數(shù) MEMBER 是 TYPE 中的一個(gè)成員變量名。

它將返回類(lèi)型為 size_t 的整數(shù),表示 MEMBER 相對(duì)于 TYPE 起始地址的偏移量。

基本原理是根據(jù) C 語(yǔ)言的數(shù)據(jù)對(duì)齊機(jī)制,成員變量在類(lèi)型定義中的相對(duì)位置決定了它的偏移量。

#defineoffsetof(TYPE,MEMBER)((size_t)&((TYPE*)0)->MEMBER)

該宏定義使用了C語(yǔ)言中的指針運(yùn)算和類(lèi)型轉(zhuǎn)換。具體實(shí)現(xiàn)步驟如下:

1、(TYPE *)0:將0強(qiáng)制類(lèi)型轉(zhuǎn)換為指向類(lèi)型為T(mén)YPE的指針,得到了一個(gè)結(jié)構(gòu)體TYPE的空指針。

2、&((TYPE *)0)->MEMBER:求出結(jié)構(gòu)體類(lèi)型TYPE中成員MEMBER的地址。其巧妙之處在于,由于空指針不指向任何對(duì)象,因此這個(gè)成員的地址就是相對(duì)于結(jié)構(gòu)體首地址的偏移量。

3、(size_t):將偏移量轉(zhuǎn)換為無(wú)符號(hào)整型數(shù),以滿足C語(yǔ)言標(biāo)準(zhǔn)庫(kù)中對(duì)offsetof()返回值的類(lèi)型要求。

該宏定義可以在編譯時(shí)就直接計(jì)算出偏移量,避免了運(yùn)行時(shí)的計(jì)算開(kāi)銷(xiāo),因此比通過(guò)變量名訪問(wèn)成員的方式更為高效,通常用在需要直接訪問(wèn)結(jié)構(gòu)體成員的底層代碼中,例如在操作系統(tǒng)內(nèi)核、嵌入式系統(tǒng)以及一些高性能計(jì)算應(yīng)用中。

structTestStruct{
intvalue1;
charvalue2;
doublevalue3;
};

size_toffset=offsetof(structTestStruct,value2);

如上例,offset 變量將會(huì)存儲(chǔ) value2 相對(duì)于 TestStruct 起始地址的偏移量。在這種情況下,因?yàn)?TestStruct 中的 value1 通常占用了 4 個(gè)字節(jié),value2 占用了 1 個(gè)字節(jié),所以 value2 相對(duì)于結(jié)構(gòu)體起始地址的偏移量應(yīng)該是 4。

2container_of

講完offsetof,來(lái)到今天的主角container_of,container_of()是一個(gè)在linux內(nèi)核中經(jīng)常使用的宏,用于獲取一個(gè)結(jié)構(gòu)體成員指針所在它所屬的結(jié)構(gòu)體的指針,有點(diǎn)繞口,細(xì)細(xì)品味。

該宏包括也主要包括三個(gè)參數(shù):

ptr:結(jié)構(gòu)體中某個(gè)成員的指針;

type:結(jié)構(gòu)體類(lèi)型名稱(chēng);

member:結(jié)構(gòu)體中ptr指向的成員名稱(chēng)。

首先,宏container_of()確定了ptr指向的成員在結(jié)構(gòu)體中的偏移(offset)。通過(guò)offsetof()宏就可以得到這個(gè)偏移,其參數(shù)為結(jié)構(gòu)體類(lèi)型和成員名稱(chēng)。得到偏移后,再通過(guò)減去偏移的方式得到指向整個(gè)結(jié)構(gòu)體的指針,巧妙吧。

具體實(shí)現(xiàn)如下:

#definecontainer_of(ptr,type,member)({
consttypeof(((type*)0)->member)*__mptr=(ptr);
(type*)((char*)__mptr-offsetof(type,member));})

其中,typeof是GCC的一個(gè)擴(kuò)展關(guān)鍵字,用于返回一個(gè)表達(dá)式的類(lèi)型,可惜,大部分非GCC編譯器不一定能支持。

假設(shè)ptr指向的成員變量的類(lèi)型為T(mén),__mptr就是一個(gè)指向T類(lèi)型的指針。然后,調(diào)用offsetof()即可得到member在type類(lèi)型中的偏移量,最后返回一個(gè)指向type類(lèi)型的指針。

注意,尖括號(hào)不能省略,因?yàn)樗硎绢?lèi)型轉(zhuǎn)換。此外,container_of()宏使用了一個(gè)GCC的語(yǔ)言擴(kuò)展"statement expression",即后面的{},可以在其中包含多條語(yǔ)句。

下面給出一個(gè)示例,用于說(shuō)明container_of()的使用方法:

#include
#include

#definecontainer_of(ptr,type,member)({
consttypeof(((type*)0)->member)*__mptr=(ptr);
(type*)((char*)__mptr-offsetof(type,member));})

structstudent{
intid;
charname[20];
};

intmain(){
structstudentstu={10001,"ZhangSan"};
char*pname=stu.name;
structstudent*pstu=container_of(pname,structstudent,name);

printf("ID:%d,Name:%s
",pstu->id,pstu->name);
return0;
}

如上例,pname指向stu的name成員,通過(guò)container_of()宏獲得了指向整個(gè)struct student結(jié)構(gòu)體的指針pstu,然后就可以訪問(wèn)id和name成員了。


審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    183

    文章

    7634

    瀏覽量

    143942
  • 結(jié)構(gòu)體
    +關(guān)注

    關(guān)注

    1

    文章

    131

    瀏覽量

    11248
  • 宏定義
    +關(guān)注

    關(guān)注

    0

    文章

    51

    瀏覽量

    9336

原文標(biāo)題:搞懂它,就可以把結(jié)構(gòu)體玩活了~

文章出處:【微信號(hào):最后一個(gè)bug,微信公眾號(hào):最后一個(gè)bug】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    C語(yǔ)言定義使用技巧

    寫(xiě)好C語(yǔ)言,漂亮的定義很重要,使用定義可以防止出錯(cuò),提高可移植性,可讀性,方便性等等。下面列舉一些成熟軟件中常用的
    發(fā)表于 07-29 09:35 ?1297次閱讀

    Linux內(nèi)核中container_of原理詳解

    Linux內(nèi)核中經(jīng)??梢?jiàn)container_of的身影,它在實(shí)際驅(qū)動(dòng)的編寫(xiě)中也是廣泛應(yīng)用。
    發(fā)表于 07-14 15:19 ?675次閱讀
    Linux內(nèi)核中<b class='flag-5'>container_of</b>原理詳解

    這個(gè)奇怪的定義要干啥???

    #define start_timer_int_ms(count) \{ \TA1CCTL0 = CCIE;\TA1CCR0 = count*5; \TA1CTL = TASSEL_1 + MC_1 + TACLR + ID__8; \}這個(gè)奇怪的
    發(fā)表于 04-20 19:22

    揭開(kāi)linux內(nèi)核中container_of的神秘面紗

    在linux 內(nèi)核中有一個(gè)大名鼎鼎的container_of(),這個(gè)是用來(lái)干嘛的呢?我們先來(lái)看看它在內(nèi)核中是怎樣定義的。呵呵,乍一看不
    發(fā)表于 11-11 10:02

    offsetofcontainer_of詳解

    // 元素元素名// 這個(gè)返回的就是指向這個(gè)結(jié)構(gòu)體變量的指針,類(lèi)型是(type *)#define container_of(ptr, type, member) ({\const
    發(fā)表于 10-13 16:35

    定義問(wèn)題!

    各位,請(qǐng)問(wèn)一下,這個(gè)定義代表什么意思?#define OUTPUT_WAVE(pointer, d)PORTC = pointer[d*N_PORTS + 0] 謝謝
    發(fā)表于 03-12 10:30

    rtdevicd.h這個(gè)文件中的定義是在哪被定義的?

    rtdevicd.h這個(gè)文件中的定義是在哪被定義
    發(fā)表于 02-03 11:49

    C語(yǔ)言定義使用技巧

    寫(xiě)好C語(yǔ)言,漂亮的定義很重要,使用定義可以防止出錯(cuò),提高可移植性,可讀性,方便性 等等。下面列舉一些成熟軟件中常用得
    發(fā)表于 11-13 12:04 ?36次下載

    內(nèi)聯(lián)函數(shù)和定義的區(qū)別介紹

    定義是C語(yǔ)言提供的三種預(yù)處理功能的其中一種,這三種預(yù)處理包括:定義、文件包含、條件編譯。定義
    發(fā)表于 12-15 15:33 ?2562次閱讀
    內(nèi)聯(lián)函數(shù)和<b class='flag-5'>宏</b><b class='flag-5'>定義</b>的區(qū)別介紹

    不帶參數(shù)的定義是什么?不帶參數(shù)的定義的資料介紹詳細(xì)過(guò)程概述

    c語(yǔ)言中有一個(gè)定義,其中有一類(lèi)就是不帶參數(shù)的定義。 定義是C提供的三種預(yù)處理功能的其中一
    發(fā)表于 09-04 15:38 ?5次下載

    使用AVR單片機(jī)編寫(xiě)的定義的應(yīng)用代碼詳細(xì)資料免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的使用AVR單片機(jī)編寫(xiě)的定義的應(yīng)用代碼詳細(xì)資料免費(fèi)下載。
    發(fā)表于 11-12 08:00 ?3次下載
    使用AVR單片機(jī)編寫(xiě)的<b class='flag-5'>宏</b><b class='flag-5'>定義</b>的應(yīng)用代碼<b class='flag-5'>詳細(xì)</b>資料免費(fèi)下載

    對(duì)于定義與重復(fù)定義的問(wèn)題

    對(duì)于定義與重復(fù)定義的問(wèn)題
    發(fā)表于 11-29 18:21 ?1次下載
    對(duì)于<b class='flag-5'>宏</b><b class='flag-5'>定義</b>與重復(fù)<b class='flag-5'>定義</b>的問(wèn)題

    Linux內(nèi)核中的/container_of分析

    今天在看平臺(tái)設(shè)備實(shí)現(xiàn)的時(shí)候,看到to_xxx開(kāi)頭的“函數(shù)”。包括在內(nèi)核中也有很多此類(lèi)的“函數(shù)”,其實(shí)他們都是container_of。因?yàn)閮?nèi)核是鏈表和結(jié)構(gòu)體的世界,因此內(nèi)核中有大量需求要 根據(jù)結(jié)構(gòu)體成員獲取結(jié)構(gòu)體地址 ,或者根據(jù)結(jié)構(gòu)體類(lèi)型和結(jié)構(gòu)體成員類(lèi)型獲取成員在結(jié)構(gòu)
    發(fā)表于 06-23 14:26 ?723次閱讀
    Linux內(nèi)核中的<b class='flag-5'>宏</b>/<b class='flag-5'>container_of</b>分析

    c語(yǔ)言帶參數(shù)的定義

    c語(yǔ)言帶參數(shù)的定義? C語(yǔ)言定義是一種替換機(jī)制,它可以將一個(gè)標(biāo)識(shí)符替換為一個(gè)代碼片段。
    的頭像 發(fā)表于 09-04 17:45 ?3224次閱讀

    container_of(),太妙了~

    的作用是通過(guò)結(jié)構(gòu)體成員的地址和結(jié)構(gòu)體類(lèi)型推導(dǎo)出結(jié)構(gòu)體的地址,type是指結(jié)構(gòu)體的類(lèi)型,member是成員在結(jié)構(gòu)體中的名字,ptr是該成員在type結(jié)構(gòu)體中的地址。
    的頭像 發(fā)表于 09-10 10:59 ?846次閱讀
    <b class='flag-5'>container_of</b>()<b class='flag-5'>宏</b>,太妙了~