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 去对比两个 ...
随机推荐
- P2471 [SCOI2007]降雨量
Description 我们常常会说这样的话:"X年是自Y年以来降雨量最多的".它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年.例如2 ...
- IntelliJ IDEA 自动导入包的问题
我们再使用IDE写代码的时候,往往需要 鼠标点中这个类 然后 使用 alt+enter ,导入响应的包,如果导入的包比较多,一个一个点 也是费事. 因为用手动,有可能需要你选择导入那个包,有时候类名 ...
- 破损的键盘(UVa 11988)
s[] 数组用来保存原有的字符序列 nex[] 数组记录打印的下标顺序 C++11 代码如下: #include<iostream> #include<cstring> usi ...
- C++ 内存分配(new,operator new)详解
参考:C++ 内存分配(new,operator new)详解 如何限制对象只能建立在堆上或者栈上 new运算符和operator new() new:指我们在C++里通常用到的运算符,比如A* a ...
- 高仿360界面的实现(用纯XML和脚本实现)
源码下载:360UI 本项目XML的桌面渲染依赖GQT开源项目(请感兴趣的朋友加入QQ讨论群:101189702,在群共享文件里下载GQT源码),以下是360界面实现的全部XML代码,所有的代码都在3 ...
- Xposed模块开发教程
转:http://vbill.github.io/2015/02/10/xposed-1/ http://blog.csdn.net/zhangmiaoping23/article/detai ...
- (转)python的range()函数用法
使用python的人都知道range()函数很方便,今天再用到他的时候发现了很多以前看到过但是忘记的细节.这里记录一下range(),复习下list的slide,最后分析一个好玩儿的冒泡程序. 转自: ...
- 谷歌pagerank算法简介
在这篇博客中我们讨论一下谷歌pagerank算法.这是参考的原博客连接:http://blog.jobbole.com/71431/ PageRank的Page可是认为是网页,表示网页排名,也可以认为 ...
- [HDU - 5408] CRB and Farm
题意: 给出一个由n个点组成的凸包,以及凸包内的k个点,问是否能够在凸包上选择最多2k个点构造一个新的 凸包,使得新的凸包覆盖原来的k个点. 要求2k个点覆盖原本的k个点,只要对原k个点构造凸包,然后 ...
- Python面向对象中super用法与MRO机制
1. 引言 最近在研究django rest_framework的源码,老是遇到super,搞得一团蒙,多番查看各路大神博客,总算明白了一点,今天做一点总结. 2. 为什么要用super 1)让代码维 ...