色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

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

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

lilihe92 ? 來源:最后一個bug ? 2023-11-13 09:45 ? 次閱讀

正文

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

1offsetof

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

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

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

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

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

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

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

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

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

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

structTestStruct{
intvalue1;
charvalue2;
doublevalue3;
};

size_toffset=offsetof(structTestStruct,value2);

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

2container_of

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

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

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

type:結(jié)構(gòu)體類型名稱;

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

首先,宏container_of()確定了ptr指向的成員在結(jié)構(gòu)體中的偏移(offset)。通過offsetof()宏就可以得到這個偏移,其參數(shù)為結(jié)構(gòu)體類型和成員名稱。得到偏移后,再通過減去偏移的方式得到指向整個結(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的一個擴(kuò)展關(guān)鍵字,用于返回一個表達(dá)式的類型,可惜,大部分非GCC編譯器不一定能支持。

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

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

下面給出一個示例,用于說明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成員,通過container_of()宏獲得了指向整個struct student結(jié)構(gòu)體的指針pstu,然后就可以訪問id和name成員了。


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

    關(guān)注

    180

    文章

    7619

    瀏覽量

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

    關(guān)注

    1

    文章

    130

    瀏覽量

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

    關(guān)注

    0

    文章

    51

    瀏覽量

    9083

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

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

收藏 人收藏

    評論

    相關(guān)推薦

    C語言定義使用技巧

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

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

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

    這個奇怪的定義要干啥???

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

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

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

    offsetofcontainer_of詳解

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

    定義問題!

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

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

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

    C語言定義使用技巧

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

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

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

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

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

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

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

    對于定義與重復(fù)定義的問題

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

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

    今天在看平臺設(shè)備實(shí)現(xiàn)的時(shí)候,看到to_xxx開頭的“函數(shù)”。包括在內(nè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)體類型和結(jié)構(gòu)體成員類型獲取成員在結(jié)構(gòu)
    發(fā)表于 06-23 14:26 ?498次閱讀
    Linux內(nèi)核中的<b class='flag-5'>宏</b>/<b class='flag-5'>container_of</b>分析

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

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

    container_of(),太妙了~

    的作用是通過結(jié)構(gòu)體成員的地址和結(jié)構(gòu)體類型推導(dǎo)出結(jié)構(gòu)體的地址,type是指結(jié)構(gòu)體的類型,member是成員在結(jié)構(gòu)體中的名字,ptr是該成員在type結(jié)構(gòu)體中的地址。
    的頭像 發(fā)表于 09-10 10:59 ?567次閱讀
    <b class='flag-5'>container_of</b>()<b class='flag-5'>宏</b>,太妙了~
    主站蜘蛛池模板: 污污内射久久一区二区欧美日韩 | 99久久精品免费精品国产 | 在线观看视频国产 | 婷婷激情综合色五月久久竹菊影视 | 88蜜桃人妻无码精品系列 | 欧美激情一区二区三区AA片 | yellow2019在线观看视频 | 白洁在线观看 | 老阿姨才是最有味的一区二区 | 末成年美女黄网站色大片连接 | 国产精品嫩草影院一区二区三区 | 免费精品国产人妻国语 | 中文字幕一区中文亚洲 | 亚洲日韩KKK444KKK聚色 | 月夜直播视频免费观看 | 美女图片131亚洲午夜 | 韩国成人理伦片免费播放 | 成人国产在线24小时播放视频 | 欧美性最猛xxxx在线观看视频 | 久久精品国产亚洲AV影院 | 97在线观看成人免费视频 | 日本撒尿特写 | 国产成人亚洲精品老王 | 亚洲一区在线视频观看 | 国产WW高清大片免费看 | 一本道久在线综合道 | 伊人草 | 91精品国产色综合久久不 | JAPANRCEP老熟妇乱子伦视频 | 蜜柚影院在线观看免费高清中文 | 亚洲青青草原 | 国产精品第1页在线观看 | 成人免费毛片观看 | 久久亚洲高清观看 | 杨幂视频1分11未删减在线观看 | 亚洲欧洲日本无在线码播放 | 免费视频xxx | 日韩欧美一区二区三区免费观看 | 动漫美女被羞羞动漫怪物 | 强奷漂亮女老板在线播放 | 年轻的搜子8中字在线观看 年轻的朋友4在线看中文字幕 |