细嚼慢咽containerof

简单版本:

一个朋友说在keil里想使用container_of函数,
然后我百度了一下,发现了这篇帖子,点击打开链接,将其复制放在keil5中编译不通过,
在了解了container_of的作用之后,自己写了一个,并且已经测试通过。

首先,
container_of的作用是从包含在某个结构中的指针获得结构本身的指针,
通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。

container_of(ptr, type, member) 
    ptr:表示结构体中member的地址
    type:表示结构体类型
    member:表示结构体中的成员

通过ptr的地址可以返回结构体的首地址

实现:#define container_of(ptr, type, member) ((type*)((ptr) - &(((type*)0)->member)))

测试:

//定义测试结构体										
struct test_struct {
           int num;
          char ch;
          float f1;
  };
 int main(void)
  {
          struct test_struct *ptest_struct;
          struct test_struct init_struct ={12,'a',12.3};
          char *ptr_ch = &init_struct.ch;		//知道此结构体中ch成员的地址 
          ptest_struct = container_of(ptr_ch,struct test_struct,ch);
          printf("init_struct =%p\n",&init_struct);
          printf("ptest_struct =%p\n",ptest_struct);
          printf("init_struct.num = %d\n",ptest_struct->num); 
          printf("init_struct.ch = %c\n",ptest_struct->ch); 
          printf("init_struct.f1 = %f\n",ptest_struct->f1); 
          return 0;
  }
测试结果
:

专业版本:

#include<stdio.h>
#include <string.h>
typedef unsigned char  uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int   uint32_t;
typedef unsigned long  long uint64_t;//注意:单片机的U64是long long 打印是llX 不是long -lX

//#define container_of(ptr, type, member) ((type*)((ptr) - &(((type*)0)->member)))

#include<stdio.h>
#include<stddef.h>
#include<stdlib.h>

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

/*ptr 成员指针
* type 结构体 比如struct Stu
* member 成员变量,跟指针对应
* */
#define container_of(ptr, type, member) ({          \
        const typeof( ((type *)0)->member ) *__mptr = (const typeof( ((type *)0)->member ) *)(ptr); \
        (type *)( (char *)__mptr - offsetof(type,member) );})


typedef struct Stu{
        int age;
        char name[10];
        int id;
        unsigned long phone_num;
}*p_stu,str_stu;

void print_all(void *p_str)
{

    p_stu m1p_stu = NULL;

    m1p_stu = container_of(p_str,struct Stu,age);

    printf("age:%d\n",m1p_stu->age);
    printf("name:%s\n",m1p_stu->name);
    printf("id:%d\n",m1p_stu->id);
    printf("phone_num:%d\n",m1p_stu->phone_num);
}

struct st
{
    char a;
    int b;
    char c;
}*p_st,n_st;

typedef st t_st;
int main(void)
{
    p_stu m_stu = (p_stu)malloc(sizeof(str_stu));
    int aa=0;
    aa=({aa=3;aa+=2;});
    printf("aa=%d\n",aa );//知识1:
    typeof(aa) bb=8;//知识2:
    printf("bb=%d\n",bb );
    printf("%p\n",&((struct st *)0)->c );
    printf("%p\n",&((t_st *)0)->b);//知识:尺子放在0位置


    m_stu->age = 25;
    m_stu->id  = 1;
    m_stu->name[0]='w';
    m_stu->name[1]='e';
    m_stu->name[2]='i';
    m_stu->name[3]='q';
    m_stu->name[4]='i';
    m_stu->name[5]='f';
    m_stu->name[6]='a';
    m_stu->name[7]='\0';
    m_stu->phone_num=13267;

    /*传结构体成员指针进去*/
    print_all(&m_stu->age);

    printf("main end\n");

    if(m_stu!=NULL)
        free(m_stu);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42381351/article/details/86573003