Linux下的两个经典宏定义 转
http://www.linuxidc.com/Linux/2016-08/134481.htm
http://www.linuxidc.com/Linux/2013-01/78003.htm
http://blog.csdn.net/npy_lp/article/details/7010752
http://www.linuxdiyf.com/viewarticle.php?id=104768
本文首先介绍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.反斜杠“/”表示行连接
Linux下的两个经典宏定义 转的更多相关文章
- Linux下的两个经典宏定义【转】
转自:http://www.linuxidc.com/Linux/2015-07/120014.htm 本文首先介绍Linux下的经典宏定义,感受极客的智慧,然后根据该经典定义为下篇文章作铺垫. of ...
- Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。
倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...
- Linux 下启动两个tomcat
Linux 下启动两个tomcat 闲来无事学习nginx,想要配置个load balance.可是先决条件是:得有两个web容器.两个电脑是不用想了.只能想办法在一个机器上启动两个tomcat.原以 ...
- Linux下配置两个或多个Tomcat启动
Linux下配置两个或多个Tomcat启动 (2012-08-14 11:59:31) 转载▼ 标签: 杂谈 分类: linux_tomcat 步骤如下: (1)修改/etc/profile文件.添加 ...
- Linux下的两种磁盘分区工具的使用
如何使用fdisk和parted分区工具来进行硬盘分区,下面我来说一下在Linux系统中这两种硬盘分区工具的使用方法: ----------fdisk分区工具---------- ...
- Linux下使用两个线程协作完成一个任务的简易实现
刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务. 打一下基础吧 本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的 ...
- Linux 下的两种分层存储方案
背景介绍 随着固态存储技术 (SSD),SAS 技术的不断进步和普及,存储介质的种类更加多样,采用不同存储介质和接口的存储设备的性能出现了很大差异.SSD 相较于传统的机械硬盘,由于没有磁盘的机械转动 ...
- Linux内核驱动基础(一)常用宏定义【转】
转自:http://blog.csdn.net/tommy_wxie/article/details/9427081 一: __init和__initdata : __exit和__exitdata ...
- Linux下对比两个文件夹的方法
最近拿到一份源代码,要命的是这份源代码是浅克隆模式的git包,所以无法完整显示里面的修改的内容. 今天花了一点点时间,找了一个在Linux对比两个文件夹的方法. 其实方法很简单,用meld 去对比两个 ...
随机推荐
- 移动web特殊样式处理
一.高清图片 二.一像素边框 还有一种解决办法: border-1px($color) position: relative &:after display: block position: ...
- C语言位域——精妙使用内存
参考链接 https://blog.csdn.net/yanbober/article/details/8697967 https://blog.csdn.net/Tommy_wxie/artic ...
- 使用html+css+js实现倒计时,开启你痛苦的倒计时吧
使用html+css+js实现倒计时,开启你痛苦的倒计时吧 效果图: 这是我痛苦的倒计时,呜呜呜 好啦,再痛苦还是要分享代码,代码如下,复制即可使用: <!DOCTYPE html> &l ...
- CSS3实现文字折纸效果
CSS3实现文字折纸效果 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <title></tit ...
- ThinkPHP中的四种路由形式
1.普通形式路由(get形式路由) 路由形式:http://网址/入库文件?m=分组&c=控制器&c=控制器&a=方法名&参数=参数 例子:http://localho ...
- hihocoder1636 Pangu and Stones(区间DP(石子合并变形))
题目链接:http://hihocoder.com/problemset/problem/1636 题目大意:有n堆石头,每次只能合并l~r堆,每次合并的花费是要合并的石子的重量,问你合并n堆石子的最 ...
- PL/SQL开发中动态SQL的使用方法
一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...
- PHP将对象转换成数组的方法(兼容多维数组类型)
/** * @author gayayang * @date 2012-8-21 * @todo 将对象转换成数组 * @param unknown_type $obj * @return unkno ...
- 面试题46:求1+2+ …… +n
题目:求1+2+…+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句(A?B:C). 通常求1+2+…+n除了用公式n(n+1)/2之外,无外 ...
- Linux查看使用端口的进程
netstat –apn | grep 8080 lsof -i:8080