container_of()宏解析

        在内核中很多地方都会使用到宏container_of()。

        都知道宏container_of()的作用是:根据结构体中一个域成员变量的指针获取指向整个结构体的指针、现在来分析这个宏是如何实现的;

        内核中container_of()代码如下:

/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:    the pointer to the member.
 * @type:   the type of the container struct this is embedded in.
 * @member: the name of the member within the struct.
 */
#define container_of(ptr, type, member) ({          \
	const typeof(((type *)0)->member)*__mptr = (ptr);    \
		     (type *)((char *)__mptr - offsetof(type, member)); })

        内核中offsetof()代码如下:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
一、理论解析

       先来说说offsetof()宏;

       1. (type *)0:将0转化为TYPE型指针;

       2. (TYPE *)0)->MEMBER:表示访问TYPE型指针0指向结构体的成员变量MEMBER;

       3. &((TYPE *)0)->MEMBER):表示取成员变量MEMBER的地址;

       4. ((size_t) :类型转化

       巧妙之处在于:将0转换成(TYPE*),然后结构体以内存空间首地址0作为起始地址,则成员地址就成为偏移地址。

       再来说说container_of()宏;

       1.  typeof(((type *)0)->member)的作用是获取成员member的结构类型;

        2. typeof(((type *)0)->member)*__mptr == (ptr);表示定义临时变量__mptr,将指针ptr赋值给__mptr;

        3. (type *)( (char *)__mptr - offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针;

二、案例解析:

        以类型struct example_st为例:

struct example_st{
	type_fst mem1;
	type_sec mem2;
	type_thd mem3;
	type_fth mem4;
};

         进行地址标记:


        container_of(sec, struct example_st, mem2))代入宏

container_of(sec, struct example_st, mem2) ({          \
	const typeof(((struct example_st *)0)->mem2)*__mptr = (sec);    \
        (struct example_st *)((char *)__mptr - offsetof(struct example_st, mem2)); })
        第三行offsetof是计算mem2在结构体struct example_st,中偏移量,等于0x0008;
        第二行可知__mptr = 0xa018;

        第三行计算结果是:0xa018 - 0x0008 = 0xa0010;

三、程序实例

list.h

/**********************************************
 * Author: lewiyon@hotmail.com
 * File name: list.h
 * Description: define some macroes
 * Date: 2011-12-29
 *********************************************/
#ifndef __LIST_H
#define __LIST_H

//typedef unsigned long size_t;

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({          \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

#endif

test.c

/**********************************************
 * Author: lewiyon@hotmail.com
 * File name: test.h
 * Description: test the macroes in the core.h 
 * Date: 2011-12-29
 *********************************************/

#include <malloc.h>
#include "list.h"

struct student{
    char *name;
    char sex;
    unsigned long id;
    int age;
    int money;
};

static struct student *id_stu(unsigned long *id_no)
{
    return (container_of(id_no, struct student, id));
}

int main(int argc, char *argv[])
{
    unsigned long offset;
    struct student *stu, *stu_tst;

    stu_tst = NULL;
    stu = (struct student *)malloc(sizeof(struct student));
    stu->name = "lewiyon"; 
    stu->sex = 'M'; 
    stu->id = 2004035000; 
    stu->age = 26; 
    stu->money =0;
    printf("-------------------------------\n");
    printf("stu         = %p\n", stu);
    printf("&stu->name  = %p\n", &stu->name);
    printf("&stu->sex   = %p\n", &stu->sex);
    printf("&stu->id    = %p\n", &stu->id);
    printf("&stu->age   = %p\n", &stu->age);
    printf("&stu->money = %p\n", &stu->money);
    printf("stu->name   = %s\n", stu->name);
    printf("-------------------------------\n");
    
    stu_tst = id_stu(&stu->id);
    offset = offsetof(struct student, id);
    printf("offset          = %p\n", offset);
    printf("stu_tst         = %p\n", stu_tst);
    printf("&stu_tst->name  = %p\n", &stu_tst->name);
    printf("&stu_tst->sex   = %p\n", &stu_tst->sex);
    printf("&stu_tst->id    = %p\n", &stu_tst->id);
    printf("&stu_tst->age   = %p\n", &stu_tst->age);
    printf("&stu_tst->money = %p\n", &stu_tst->money);
    printf("stu_tst->name   = %s\n", stu_tst->name);

    return 0;
}

转载于:https://www.cnblogs.com/youngerchina/archive/2011/12/29/5624638.html

内容概要:该题库专为研究生入学考试计算机组成原理科目设计,涵盖名校考研真题、经典教材课后习题、章节题库和模拟试题四大核心模块。名校考研真题精选多所知名高校的计算机组成原理科目及计算机联考真题,并提供详尽解析,帮助考生把握考研命题趋势与难度。经典教材课后习题包括白中英《计算机组成原理》(第5版)和唐朔飞《计算机组成原理》(第2版)的全部课后习题解答,这两部教材被众多名校列为考研指定参考书目。章节题库精选代表性考题,注重基础知识与重难点内容,帮助考生全面掌握考试大纲要求的知识点。模拟试题依据历年考研真题命题规律和热门考点,精心编制两套全真模拟试题,并附标准答案,帮助考生检验学习成果,评估应试能力。 适用人群:计划参加研究生入学考试并报考计算机组成原理科目的考生,尤其是需要系统复习和强化训练的学生。 使用场景及目标:①通过研读名校考研真题,考生可以准确把握考研命题趋势与难度,有效评估复习成效;②通过经典教材课后习题的练习,考生可以巩固基础知识,掌握解题技巧;③通过章节题库的系统练习,考生可以全面掌握考试大纲要求的各个知识点,为备考打下坚实基础;④通过模拟试题的测试,考生可以检验学习成果,评估应试能力,为正式考试做好充分准备。 其他说明:该题库不仅提供详细的题目解析,还涵盖了计算机组成原理的各个方面,包括计算机系统概述、数据表示与运算、存储器分层、指令系统、中央处理器、总线系统和输入输出系统等。考生在使用过程中应结合理论学习与实践操作,注重理解与应用,以提高应试能力和专业知识水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值