转自:http://www.linuxidc.com/Linux/2015-07/120014.htm

本文首先介绍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 = %d\n", gender_offset);
 printf("id_offset = %d\n", id_offset);
 printf("age_offset = %d\n", age_offset);
 printf("name_offset = %d\n", 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

本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/7131789.html,如需转载请自行联系原作者

Linux下的两个经典宏定义【转】相关推荐

  1. Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。...

    倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...

  2. Linux中的两个经典宏定义

    倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...

  3. Linux内核源码中使用宏定义的若干技巧

    在C中,宏定义的概念虽然简单,但是真要用好却并不那么容易,下面从Linux源码中抽取一些宏定义的使用方法,希望能从中得到点启发: 1. 类型检查 比如module_init的宏定义: 点击(此处)折叠 ...

  4. Linux下将两个10G的文件打包成一个文件需要多久

    Linux下将两个10G的文件打包成一个文件需要多久 | 公云网博客 Linux下将两个10G的文件打包成一个文件需要多久 发表于 2012 年 9 月 19 日 由 refactor 微博上kevi ...

  5. 【C语言】Linux内核源码--min,swap宏定义

    Linux3.5的部分宏定义在linux-3.5/include/linux/kernel.h的头文件中有定义 一: 最大值和最小值相关的宏 /** min()/max()/clamp() macro ...

  6. linux系统下集群共享磁盘sdb分区,Linux下的两种磁盘分区工具的使用

    今天我们来说一下如何使用fdisk和parted分区工具来进行硬盘分区,.下面我来说一下在Linux系统中这两种硬盘分区工具的使用方法: ----------fdisk分区工具---------- 在 ...

  7. Linux下使用两个线程协作完成一个任务的简易实现

    刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务. 打一下基础吧 本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的 ...

  8. linux下安装两个nginx教程,在linux系统下安装两个nginx的简单方法

    在linux系统下安装两个nginx的简单方法 发布时间:2017-03-09 12:08 来源:互联网 当前栏目:web技术类 在linux下安装nginx的时候,一般在./configure的阶段 ...

  9. linux socket 编程 —— 霸气的宏定义

    高考完了,闲着没事, 想写一个 c/s ,但是在 协议域 装入有了一些问题. struct sockaddr_in servaddr;servaddr.sin_port = 6789;servaddr ...

最新文章

  1. Caused by java.lang.ClassNotFoundException javax.xml.bind.ValidationException异常
  2. mysql查看客户端执行的语句_查看MySQL最近执行的语句-阿里云开发者社区
  3. 超大规模集成电路先进光刻理论与应用_中科院上海光机所光刻机投影物镜热效应模型研究取得进展...
  4. 云开发初探 —— 更简便的小程序开发模式
  5. MATLAB实现主成分分析
  6. 迅捷pdf转换器(文件格式转换器)
  7. 怎么用python扫描主机_python 扫描内网存活主机
  8. python入门经典.pdf
  9. Himall商城LinqHelper帮助类(1)
  10. 高仿京东分类页面实现
  11. Python 中 set 的基本用法
  12. 利用Yocto构建嵌入式Linux教程3_1--Yocto构建系统的配置文件
  13. 区块链金融中的python应用--LSM定价
  14. 如何读取蓝牙linkkeys值
  15. scala简介 什么是Scala?
  16. 工具 xshell无法使用,需要更新的问题
  17. U盘安装ubuntu20.04 Linux系统分区方案 Invalid Partition Table
  18. CSDN中markdown编辑器如何实现首行缩进
  19. Eq计算机中,EQ(均衡器)的用法
  20. buzz fizz 翻译_(点读)The Fizz-Buzz

热门文章

  1. 高大上!手把手教你在京东云擎上部署个人应用!
  2. Linux基础命令---检查密码文件pwck 1
  3. SpringCache实战遇坑
  4. 爬虫调用百度翻译API
  5. AVCaptureDevice 属性介绍
  6. Python零基础学习系列之三--Python编辑器选择
  7. 为什么别人一周搞定Linux,而你却做不到
  8. ASP.NET 导入 Excel
  9. 2.VMware View 4.6安装与部署-域环境
  10. 【整数转字符串】LeetCode 9. Palindrome Number