C語言之offsetof宏和container_of宏

  首先咱們要明白一點經過結構體變量來訪問結構體中的各個元素時,其本質上是ide

經過指針的方式來實現訪問的,只不過是這個時候編譯器幫自動幫咱們計算了每一個spa

元素與結構體起始地址之間的偏移量而已指針


一:offsetof宏:編譯器

#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)

1:參數與返回值分析:it

 (1)TYPE是結構體類型,MEMBER是結構體中一個元素的元素名編譯

  (2)這個宏返回的是member元素相對於整個結構體變量的首地址的偏移量,類型是intclass

2:做用於原理變量

  (1)offsetof宏的做用是:用宏來計算結構體中某個元素和結構體首地址的偏移原理

量(其實質是經過編譯器來幫咱們計算)。數據類型

  (2)offsetof宏的原理:咱們虛擬一個type類型結構體變量,而後用type.member

的方式來訪問那個member元素,繼而獲得member相對於整個變量首地址的偏移量。

3:從結合方式方面來分析:

(TYPE *)0 這是一個強制類型轉換,把0地址強制類型轉換成一個指針,這個指針指

向一個TYPE類型的結構體變量。 (實際上這個結構體變量可能不存在,可是隻要我

不去解引用這個指針就不會出錯)。


((TYPE *)0)->MEMBER (TYPE *)0是一個TYPE類型結構體變量的指針,經過指針指針

來訪問這個結構體變量的member元素


&((TYPE *)0)->MEMBER  等效於&(((TYPE *)0)->MEMBER),意義就是獲得member元

素的地址。可是由於整個結構體變量的首地址是0,因此獲得的member元素的地址就

是member元素的偏移量。


二:container_of宏

#define container_of(ptr, type, member) ({\
const typeof(((type *)0)->member) * __mptr = (ptr);\
(type *)((char *)__mptr - offsetof(type, member)); }
注意:這裏的 \ 是連行符

1:參數與返回值分析:

 (1)ptr是指向結構體元素member的指針,type是結構體類型,member是結構體

中一個元素的元素名

 (2)這個宏返回的就是指向整個結構體變量的指針,類型是(type *)

2:做用與原理分析:

  (1)做用:知道一個結構體中某個元素的指針,反推這個結構體變量的指針。有

了container_of宏,咱們能夠從一個元素的指針獲得整個結構體變量的指針,繼而

獲得結構體中其餘元素的指針。

  (2)typeof關鍵字的做用是:typepof(a)時由變量a獲得a的類型,typeof就是由

變量名獲得變量數據類型的。

  (3)這個宏的工做原理:先用typeof獲得member元素的類型定義成一個指針,然

後用這個指針減去該元素相對於整個結構體變量的偏移量(偏移量用offsetof宏得

到的),減去以後獲得的就是整個結構體變量的首地址了,再把這個地址強制類型

轉換爲type *便可。

相關文章
相關標籤/搜索