2021-05-12 14:32:11
Linux下的兩個經典宏定義
本文首先介紹Linux下的經典宏定義,感受極客的智慧,然後根據該經典定義為下篇文章作鋪墊。
offsetof宏定義:
// 獲得結構體(TYPE)的變數成員(MEMBER)在此結構體中的偏移量。
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
說明:獲得結構體(TYPE)的變數成員(MEMBER)在此結構體中的偏移量。
1.( (TYPE *)0 ) 將零轉型為TYPE型別指標,即TYPE型別的指標的地址是0。
2.((TYPE *)0)->MEMBER 存取結構中的資料成員。
3.&( ( (TYPE *)0 )->MEMBER ) 取出資料成員的地址。由於TYPE的地址是0,這裡獲取到的地址就是相對MEMBER在TYPE中的偏移。
4.(size_t)(&(((TYPE*)0)->MEMBER)) 結果轉換型別。對於32位元系統而言,size_t是unsigned int型別;對於64位元系統而言,size_t是unsigned long型別。
使用範例:
struct student
{
char gender;
int id;
int age;
char name[20];
};
int _tmain(int argc, _TCHAR* argv[])
{
int gender_offset, id_offset, age_offset, name_offset;
gender_offset = offsetof(struct student, gender);
id_offset = offsetof(struct student, id);
age_offset = offsetof(struct student, age);
name_offset = offsetof(struct student, name);
printf("gender_offset = %dn", gender_offset);
printf("id_offset = %dn", id_offset);
printf("age_offset = %dn", age_offset);
printf("name_offset = %dn", name_offset);
system("pause");
return 0;
}
//結果:
/*
gender_offset = 0
id_offset = 4 //位元組對其
age_offset = 8
name_offset = 12
*/
offsetof圖解
TYPE是結構體,它代表"整體";而MEMBER是成員,它是整體中的某一部分。
container_of宏定義:
#define container_of(ptr, type, member) ({
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
說明:根據"結構體(type)變數"中的"域成員變數(member)的指標(ptr)"來獲取指向整個結構體變數的指標。
1. typeof( ( (type *)0)->member ) 取出member成員的變數型別。
2.const typeof( ((type *)0)->member ) *__mptr = (ptr) 定義變數__mptr指標,並將ptr賦值給__mptr。經過這一步,__mptr為member資料型別的常數指標,其指向ptr所指向的地址。
3. (char *)__mptr 將__mptr轉換為位元組型指標。
4. offsetof(type,member)) 就是獲取"member成員"在"結構體type"中的位置偏移。
5. (char *)__mptr - offsetof(type,member)) 就是用來獲取"結構體type"的指標的起始地址(為char *型指標)。
6.(type *)( (char *)__mptr - offsetof(type,member) ) 就是將"char *型別的結構體type的指標"轉換為"type *型別的結構體type的指標"。
7.反斜槓“/”表示行連線
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-07/120014p2.htm
相關文章