C语言笔记(结构体与offsetof、container_of之前的关系)
关于结构体学习,需要了解:结构体的定义和使用、内存对齐、结构体指针、得到结构体元素的偏移量(offsetof宏实现)
一、复习结构体的基本定义和使用
typedef struct mystruct
{
int a;
char b;
double c;
}MyS1; /*
函数功能:演示结构体的定义和使用
*/
void func1(void)
{
//定义时赋值
MyS1 s1 = {
.a =,
.b =,
.c = 1.23,
};
printf("s1.a = %d.\n", s1.a);
printf("s1.b = %d.\n", s1.b);
printf("s1.c = %f.\n", s1.c);
printf("value is change.\n");
// 使用.访问方式赋值
s1.a = ;
s1.b = ;
s1.c = 3.12; printf("s1.a = %d.\n", s1.a);
printf("s1.b = %d.\n", s1.b);
printf("s1.c = %f.\n", s1.c);
}
结果:
分析:主要是复习一下结构体的定义和使用。
二、结构体指针的使用
typedef struct mystruct
{
int a;
char b;
double c;
}MyS1;
/*
函数功能:演示结构体指针的使用
*/
void func2(MyS1 *s_temp)
{
s_temp->a = ;
s_temp->b = ;
s_temp->c = 56.123;
printf("s_temp->a = %d.\n", s_temp->a);
printf("s_temp->a = %d.\n", s_temp->b);
printf("s_temp->a = %f.\n", s_temp->c);
}
int main(void)
{
MyS1 s1;
MyS1 *ps1 = &s1;
func2(ps1);
return ;
}
结果:
三、offsetof宏详解
先看看代码,是如何使用offsetof的
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) struct mystruct
{
int a;
char b;
double c;
};
int adr_a = offsetof(struct mystruct, b); // adr_a = 4
offsetof宏的分析: #define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
1、功能:返回结构体元素的相对结构体首地址的偏移
2、参数:TYPE是结构体类型,MEMBER是结构体中一个元素的元素名
3、分析:
(1) (TYPE *)0; 将0转换成结构体指针;
(2) ((TYPE *)0)->MEMBER; 使用指针方式访问结构体中元素
(3) &(((TYPE *)0)->MEMBER); 取结构体中元素的地址
(4) (int) &(((TYPE *)0)->MEMBER); 转换成int型返回
四、container_of宏详解
先看代码
#define container_of(ptr, type, member) ({ \
const typeof(((type *))->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member));}) typedef struct mystruct
{
int a;
char b;
double c;
}MyS1;
struct mystruct s1;
MyS1 *ps = NULL;
double *p = &s1.c;
printf("&s1 = %p.\n" ,&s1); ps = container_of(p, MyS1, c);
printf("ps = %p.\n" ,ps);
结果:
分析:根据&s1.c的地址得到整个结构体的首地址
详解:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member));})
1、功能:返回整个结构体变量的指针
2、参数:ptr是指向结构体中一个元素的指针;type是结构体类型;member是结构体中一个元素的元素名
3、分析:
(1) typeof(((type *)0)->member); 获取结构体中一个元素的类型;s1.c 的类型是double
(2) const typeof(((type *)0)->member) * __mptr = (ptr);
就可以理解为:
const double * __mptr = (ptr);//__mptr指向ptr处
(3) (char *)__mptr - offsetof(type, member); // 结构体其中一个元素的地址 - 该元素相对结构体首地址的偏移
(4) (type *)((char *)__mptr - offsetof(type, member)); // 转换成该结构体类型的指针返回
-----------------------------------------------------------------------------------------------------------------------------------
注:以上程序是参考“朱老师物联网视频”中的代码,特此申明!
----------------------------------------------------------------------------------------------------------------------------
C语言笔记(结构体与offsetof、container_of之前的关系)的更多相关文章
- 瘋子C语言笔记(结构体/共用体/枚举篇)
(一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student { int num; char name ...
- 01.C语言关于结构体的学习笔记
我对于学习的C语言的结构体做一个小的学习总结,总结如下: 结构体:structure 结构体是一种用户自己建立的数据类型,由不同类型数据组成的组合型的数据结构.在其他高级语言中称为记录(record) ...
- C语言链表结构体(学习笔记)
#include <stdio.h> #define LENTEST 100 // 采取逐步删除的方法求的素数 //先假设1-100都是素数,然后剔除2的倍数, //3的倍数,直到剔除所有 ...
- C语言中结构体对齐问题
C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...
- C语言中结构体赋值问题的讨论
今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...
- C语言的结构体和C++结构体的区别
关于C++中声明结构体中需要使用构造器创建实例对象的语法: <C++的结构体构造方法的基本概念:结构体的构造方法需要和结构体的名字相同,并且无返回值,也不要void关键字,这样的方法就是构造器的 ...
- 逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式
逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式 一丶了解什么是结构体,以及计算结构体成员的对其值以及总大小(类也是这样算) 结构体的特性 1.结构体(struct)是由一系列具有相同类型或不 ...
- C语言中结构体赋值问题的讨论(转载)
今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...
- go语言学习-结构体
结构体 go语言中的结构体,是一种复合类型,有一组属性构成,这些属性被称为字段.结构体也是值类型,可以使用new来创建. 定义: type name struct { field1 type1 fie ...
- 将c语言的结构体定义变成对应的golang语言的结构体定义,并将golang语言结构体变量的指针传递给c语言,cast C struct to Go struct
https://groups.google.com/forum/#!topic/golang-nuts/JkvR4dQy9t4 https://golang.org/misc/cgo/gmp/gmp. ...
随机推荐
- 如何解决升级WIN服务的时候,不暴力停止服务 达到升级的目的
同一个WIN服务,分别部署在A.B两台服务器上,前面使用netscaler负载均衡 ,A和B被请求频繁,几乎时时刻刻都被请求 .PS:发布WIN服务的正常流程是,停止WIN服务->发布WIN ...
- maven上传自定义jar到本地仓库
mvn install:install-file -Dfile=D:/baidu/ueditor-1.1.1.jar -DgroupId=com.baidu.ueditor -Dartifact ...
- B - Dungeon Master
题目大意: 地牢大师(感觉像是一款游戏啊.......) 你被困在一个3D的地牢里面,并且需要发现最快的出去的路,这个地牢由很多小立方体组成,有的是空的可以走,有的被岩石填充了不可以走,移动一 ...
- Web前端之HTML
一. HTML介绍: 1.HTML:超文本标记语言. 2.HTML是由:标签和内容构成. 3.程序语言有两种:解释性语言(HTML.PHP.Python.Javascript)和编译型语言(C.C++ ...
- Hadoop2.6.0在Ubuntu Kylin14.04上的配置
最近几天在忙参加一个云计算比赛,之前也在Ubuntu上配成功过hadoop,不过是按照书上讲的,一步一步来的.因此,印象不深,对自己的帮助也不大.这次趁着机会,自己练了两遍配置过程,感觉收获比较丰富, ...
- bzoj 3225: [Sdoi2008] 立方体覆盖 题解
[原题] 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory Limit: 128 MB Submit: 51 Solved: 36 [Submit][S ...
- Core Foundation框架介绍
Core Foundation框架介绍 **参考网址: ARC下OC对象和CF对象之间的桥接 Core Foundation框架介绍 Core Foundation框架 Core Foundation ...
- u盘安装linux(windows7+linux双系统)
前提条件:1.先装windows7,后装linux系统 2.windows7 里有“未分区的空间”(不是C:,D:,E:) :计算机→管理→存储空间,删除一些压缩卷即可. 3.下载ultraiso → ...
- Java多态性举例说明
Java多态性的概念也可以被说成“一个接口,多个方法”. (一)相关类 class A ...{ public String show(D obj)...{ return ("A and D ...
- Quartz简单使用
官方的Quartz会提供例子的,例子看个前三四个感觉就够用了,主要就是起Timer的作用,但是比timer稳定,而且功能更全. UpdateClientTimer.task(ClearJob.clas ...