当前位置:网站首页>函数简介篇——container_of 宏的理解
函数简介篇——container_of 宏的理解
2022-08-07 18:45:00 【惺忪牛犊子】
说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
QQ 群 号:513683159 【相互学习】
内容来源:
1.功能简介:
若仅知某 结构体的数据类型 和其中一个 成员变量的数据类型和变量名,但想对该结构体变量中其他成员变量进行操作,则需先得到该 结构体变量首地址。则可采用container_of宏进行获得。
2.源码及注释:
/** * @brief 通过“结构体成员”的地址与“结构体”的类型推导出“结构体”的首地址 * * @ptr: “结构体成员”的地址 * @type: “结构体”的类型 * @member: “结构体成员”的名字 */
#ifndef container_of
#define container_of(ptr, type, member) \ ({
\ const typeof(((type *)NULL)->member) *__mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); \ })
#endif
/* (1).typeof()返回传入数据的类型,如int a = 3;typeof(a) = int (2.offsetof(type, member):在类型为type的结构体中member成员,在该结构体中的偏移量 type:结构体类型,member:结构体中某个成员 分析: A = ((type *) NULL)表示:type类型的指针地址为0, B = (A->member)表示:该结构体类型(地址为0)的成员member C = typeof(B)表示:返回结构体成员member的数据类型 D = const C* __mptr = (ptr)表示:__mptr的地址为ptr的成员地址(数据类型统一的成员地址) E = offsetof(type, member)表示:类型为type的结构体中member成员,member在该结构体中的偏移量 F = (type *) ((char *)__mptr - E = ptr - E (忽略类型) = 成员的地址 - 成员的偏移量 = 结构体的的初始地址 = 结构体指针地址 */
3.源文件测试理解步骤
#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>
#ifndef container_of
#define container_of(ptr, type, member) \ ({
\ const typeof(((type *)NULL)->member) *__mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); \ })
#endif
struct test_struct
{
int data;
bool pending;
char name;
void *pointer;
};
int main(int argc, char *argv[])
{
/* 1.理解typedef关键字的作用 typeof(((struct test_struct *)NULL)->name) = char typeof()返回传入数据的类型,如int a = 3;typeof(a) = int */
const typeof(((struct test_struct *)NULL)->name) a = 'a';
printf("%c\n", a);
/* 2.获取结构体成员的地址 const typeof(((type *)NULL)->member) *__mptr = (ptr); 根据结构体成员名得到结构体成员名的数据类型,再将已知的成员地址传入 */
struct test_struct data;
const typeof(((struct test_struct *)NULL)->name)* _a = &data.name;
printf("member address:%p\n", _a);
/* 3.获取结构体成员的地址与结构体的偏移量 offsetof(type, member) 在类型为type的结构体中member成员,在该结构体中的偏移量 */
printf("member offset:%ld\n", offsetof(struct test_struct, name));
/* 4.最终结果,获得结构体地址 */
printf("struct address:%p\n", \
(struct test_struct *)((char *)_a - offsetof(struct test_struct, name)));
printf("struct address:%p\n", &data);
return 0;
}
边栏推荐
- 9.paddlepaddle中squeeze的用法,裁剪到想要维度
- win32&mfc————win32消息机制
- 网页翻译插件
- [chestnut sugar GIS] DOS - how to delete a specific folder
- [2022 Nioke Duo School 4 C] Easy Counting Problem (generating function NTT)
- tiup cluster reload
- [GStreamer] undefined symbol: gst_push_src_get_type
- Dispatchers principle of Kotlin coroutine
- dart中int类型变量与String类型变量拼接的三种方式
- 1. How a chip is born
猜你喜欢

1. How a chip is born

Lufax management turmoil: Ji Guangheng resigns as chairman, CFO Zheng Xigui also retires
![[chestnut sugar GIS] DOS - how to extract the folder name](/img/c9/3e37571faf98fad6012152c9ffc5bd.png)
[chestnut sugar GIS] DOS - how to extract the folder name

全球首个!元宇宙安全极客大会来了

SAS Planet download satellite map

翻译软件在线翻译

英文转换-在线英文批量转换器免费

Which translation software is more accurate

企业文化如何治好企业“内耗”?

认识UDS诊断29认证服务
随机推荐
Three ways to splicing int type variables and String type variables in dart
Free translation software - batch automatic one-click translation
MySQL SQL语句限制参数
【Token】JWT uses Token to log in
What is the difference between registered company capital subscription and actual payment?
tiup cluster replay
Dispatchers principle of Kotlin coroutine
[chestnut sugar GIS] DOS - how to create subfolders in batches inside the current folder
Lufax management turmoil: Ji Guangheng resigns as chairman, CFO Zheng Xigui also retires
Audio and video development journey (66) - the principle of audio variable speed without pitch
vim you can also write text blocks
网页翻译插件
国内多位架构大牛强烈推荐的大型分布式手册
物联网技术概论:第7章
离线地图下载和发布
Haochen Software IPO meeting: annual revenue of 240 million to raise 750 million Sequoia is a shareholder
How can corporate culture cure corporate "internal friction"?
个体工商户注册登记流程!(详细版)
ResNet Architecture Analysis
[2022 Nioke Duo School 2 E] Falfa with Substring (binomial inversion NTT)