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

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

詳細聊聊container_of這個宏定義

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

正文

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

1offsetof

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

其第一個參數 TYPE 是一個結構體類型,第二個參數 MEMBER 是 TYPE 中的一個成員變量名。

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

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

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

該宏定義使用了C語言中的指針運算和類型轉換。具體實現步驟如下:

1、(TYPE *)0:將0強制類型轉換為指向類型為TYPE的指針,得到了一個結構體TYPE的空指針。

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

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

該宏定義可以在編譯時就直接計算出偏移量,避免了運行時的計算開銷,因此比通過變量名訪問成員的方式更為高效,通常用在需要直接訪問結構體成員的底層代碼中,例如在操作系統內核、嵌入式系統以及一些高性能計算應用中。

structTestStruct{
intvalue1;
charvalue2;
doublevalue3;
};

size_toffset=offsetof(structTestStruct,value2);

如上例,offset 變量將會存儲 value2 相對于 TestStruct 起始地址的偏移量。在這種情況下,因為 TestStruct 中的 value1 通常占用了 4 個字節,value2 占用了 1 個字節,所以 value2 相對于結構體起始地址的偏移量應該是 4。

2container_of

講完offsetof,來到今天的主角container_of,container_of()是一個在linux內核中經常使用的宏,用于獲取一個結構體成員指針所在它所屬的結構體的指針,有點繞口,細細品味。

該宏包括也主要包括三個參數:

ptr:結構體中某個成員的指針;

type:結構體類型名稱;

member:結構體中ptr指向的成員名稱。

首先,宏container_of()確定了ptr指向的成員在結構體中的偏移(offset)。通過offsetof()宏就可以得到這個偏移,其參數為結構體類型和成員名稱。得到偏移后,再通過減去偏移的方式得到指向整個結構體的指針,巧妙吧。

具體實現如下:

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

其中,typeof是GCC的一個擴展關鍵字,用于返回一個表達式的類型,可惜,大部分非GCC編譯器不一定能支持。

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

注意,尖括號不能省略,因為它表示類型轉換。此外,container_of()宏使用了一個GCC的語言擴展"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結構體的指針pstu,然后就可以訪問id和name成員了。


審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7604

    瀏覽量

    136692
  • 結構體
    +關注

    關注

    1

    文章

    130

    瀏覽量

    10840
  • 宏定義
    +關注

    關注

    0

    文章

    50

    瀏覽量

    9005

原文標題:搞懂它,就可以把結構體玩活了~

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

收藏 人收藏

    評論

    相關推薦

    C語言定義使用技巧

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

    Linux內核中container_of原理詳解

    Linux內核中經常可見container_of的身影,它在實際驅動的編寫中也是廣泛應用。
    發表于 07-14 15:19 ?312次閱讀
    Linux內核中<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; \}這個奇怪的
    發表于 04-20 19:22

    揭開linux內核中container_of的神秘面紗

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

    offsetofcontainer_of詳解

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

    定義問題!

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

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

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

    C語言定義使用技巧

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

    內聯函數和定義的區別介紹

    定義是C語言提供的三種預處理功能的其中一種,這三種預處理包括:定義、文件包含、條件編譯。定義
    發表于 12-15 15:33 ?2338次閱讀
    內聯函數和<b class='flag-5'>宏</b><b class='flag-5'>定義</b>的區別介紹

    不帶參數的定義是什么?不帶參數的定義的資料介紹詳細過程概述

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

    使用AVR單片機編寫的定義的應用代碼詳細資料免費下載

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

    對于定義與重復定義的問題

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

    Linux內核中的/container_of分析

    今天在看平臺設備實現的時候,看到to_xxx開頭的“函數”。包括在內核中也有很多此類的“函數”,其實他們都是container_of。因為內核是鏈表和結構體的世界,因此內核中有大量需求要 根據結構體成員獲取結構體地址 ,或者根據結構體類型和結構體成員類型獲取成員在結構
    發表于 06-23 14:26 ?395次閱讀
    Linux內核中的<b class='flag-5'>宏</b>/<b class='flag-5'>container_of</b>分析

    c語言帶參數的定義

    c語言帶參數的定義? C語言定義是一種替換機制,它可以將一個標識符替換為一個代碼片段。
    的頭像 發表于 09-04 17:45 ?2401次閱讀

    container_of(),太妙了~

    的作用是通過結構體成員的地址和結構體類型推導出結構體的地址,type是指結構體的類型,member是成員在結構體中的名字,ptr是該成員在type結構體中的地址。
    的頭像 發表于 09-10 10:59 ?487次閱讀
    <b class='flag-5'>container_of</b>()<b class='flag-5'>宏</b>,太妙了~
    主站蜘蛛池模板: 欧美重口绿帽video| 高清 仑乱 一级 a| 国产高清视频a在线大全| 亚洲一区二区三区高清网| 午夜射精日本三级| 少妇高潮惨叫久久久久久欧美 | asmr淫语| 99久久无码热高清精品| 中文字幕在线免费观看视频| 伊人久久综合影院首页| 亚洲综合春色另类久久| 亚洲熟妇色自偷自拍另类| 亚洲香蕉视频在线播放| 亚洲欧美中文日韩v在线| 亚洲乱码中文字幕久久| 亚洲人精品午夜射精日韩| 亚洲精品成A人在线观看| 亚洲嫩草影院久久精品 | 男插女高潮一区二区| 男人J桶进男人屁股过程| 内射白嫩少妇超碰| 欧美怡红院视频一区二区三区 | 毛片手机在线看| 欧美videqsdesex0| 日本xxx在线观看免费播放| 日日干夜夜艹| 性派对xxxhd| 伊人久久伊人| 98久久无码一区人妻A片蜜| WWW国产亚洲精品久久| 芳草地社区在线视频| 国产乱国产乱老熟300部视频| 好大好硬好爽好深好硬视频| 久久99免费视频| 免费国产综合视频在线看| 人妻激情综合久久久久蜜桃| 甜性涩爱下载| 一个人的视频在线观看免费观看 | 97午夜精品| 公么我好爽再深一点| 国厂精品114福利电影|