container_of使用小结
先上演示代码
#include <stdio.h>
#include <stdlib.h> /* offsetof example */
#include <stddef.h> /* offsetof */ //#define offsetof(type, member) (size_t)&(((type*)0)->member)
/**
* container_of - 通过结构体的一个成员获取容器结构体的指针
* @ptr: 指向成员的指针。
* @type: 成员所嵌入的容器结构体类型。
* @member: 结构体中的成员名。
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *))->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );}) typedef struct student_info
{
int id;
char name[];
int age;
}student_info; #define DEBUG_COUT(var) do{printf(#var"= %d\n",(int)var);}while(0)
#define DEBUG_POINT(var) do{printf(#var"= %p\n",var);}while(0)
int main(void)
{ printf ("************offsetof example************\n");
DEBUG_COUT(offsetof(student_info,id));
DEBUG_COUT(offsetof(student_info,name));
DEBUG_COUT(offsetof(student_info,age));
printf ("************container_of example************\n");
student_info *stu = (student_info *)malloc(sizeof(student_info));
stu->age = ;
student_info *ptr = container_of(&(stu->age), student_info, age);
DEBUG_POINT(stu);//printf("stu address:%p\n", stu);
DEBUG_POINT(ptr);//printf("ptr address:%p\n", ptr);
DEBUG_COUT(ptr->age); system("pause");
return ;
}
make一下并且测试一下

/**
* container_of - 通过结构体的一个成员获取容器结构体的指针
* @ptr: 指向成员的指针。
* @type: 成员所嵌入的容器结构体类型。
* @member: 结构体中的成员名。
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *))->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
这个宏的作用其实很简单,就是通过一个容器(结构体)中某个成员的指针得到指向这个容器(结构体)的指针,简单的说就是通过成员找容器。

container_of使用小结的更多相关文章
- typeof, offsetof 和container_of
要理解Linux中实现的双向循环链表("侵入式"链表),首先得弄明白宏container_of. 本文尝试从gcc的关键字typeof和宏offsetof入手,循序渐进地剖析宏co ...
- 嵌入式C语言自我修养 04:Linux 内核第一宏:container_of
4.1 typeof 关键字 ANSI C 定义了 sizeof 关键字,用来获取一个变量或数据类型在内存中所占的存储字节数.GNU C 扩展了一个关键字 typeof,用来获取一个变量或表达式的类型 ...
- linux中container_of
linux 驱动程序中 container_of宏解析 众所周知,linux内核的主要开发语言是C,但是现在内核的框架使用了非常多的面向对象的思想,这就面临了一个用C语言来实现面向对象编程的问题,今天 ...
- 从零开始编写自己的C#框架(26)——小结
一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...
- Python自然语言处理工具小结
Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...
- java单向加密算法小结(2)--MD5哈希算法
上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...
- iOS--->微信支付小结
iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...
- iOS 之UITextFiled/UITextView小结
一:编辑被键盘遮挡的问题 参考自:http://blog.csdn.net/windkisshao/article/details/21398521 1.自定方法 ,用于移动视图 -(void)mov ...
- K近邻法(KNN)原理小结
K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...
随机推荐
- Flume 安装和配置
安装步骤 1.安装jdk,1.6版本以上 2.上传flume的安装包 3.解压安装 4.在conf目录下,创建一个配置文件,比如:template.conf(名字可以不固定,后缀也可以不固定) 5.配 ...
- 知识点:java 注解 @SuppressWarnings
前言: 简介:java.lang.SuppressWarnings是J2SE5.0中标准的Annotation之一.可以标注在类.字段.方法.参数.构造方法,以及局部变量上.作用:告诉编译器忽略指定的 ...
- c#day03
c#中的随机数 Random random = new Random(); //随机1~200之间的一个数 random.Next(,); //怪兽:防御为10,血量为10 //玩家:随机8~12的攻 ...
- 进程间通信IPC (InterProcess Communication)
一.进程间通信的概念 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区, ...
- MySql存储过程与函数详解
存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在MyS ...
- react学习笔记(一)
React的介绍: React来自于Facebook公司的开源项目 React 可以开发单页面应用 spa(单页面应用) react 组件化模块化 开发模式 React通过对DOM的模拟(虚拟dom) ...
- Page Cache, the Affair Between Memory and Files.页面缓存-内存与文件的那些事
原文标题:Page Cache, the Affair Between Memory and Files 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限 ...
- 初学Jmeter添加Http请求,执行接口测试
最近测试并发,刚开始使用的是录制方法,后面发现录制后无任何界面,加参数也不知从何着手,于是查了很多文章,终于慢慢的着手从http请求来测试并发了. 当然这是个遗留问题,先放在这里后面清楚了再回来补充: ...
- 关于微信小程序更新内容后手机上不能及时显示的办法
这几天一直在做微信小程序的二次开发,每天都要发布程序,但是发布之后微信上查看小程序和以前的一模一样,丝毫没有改变,但是我再本地上却改变了,而且没有开的不校验合法域名那个.这是为啥呢????? 这是跟小 ...
- for循环执行时在,每执行一次for循环中弹出提示框,延时问题
在需求中,ajax的返回值,根据数组内容的长度去做循环,每循环一次弹出提示框,发现for循环的执行速度非常之快,想到了延时,但是在for循环中延时并不能解决这个问题. 查到setTimeout的递归处 ...