关于结构体学习,需要了解:结构体的定义和使用、内存对齐、结构体指针、得到结构体元素的偏移量(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之前的关系)的更多相关文章

  1. 瘋子C语言笔记(结构体/共用体/枚举篇)

    (一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student { int num; char name ...

  2. 01.C语言关于结构体的学习笔记

    我对于学习的C语言的结构体做一个小的学习总结,总结如下: 结构体:structure 结构体是一种用户自己建立的数据类型,由不同类型数据组成的组合型的数据结构.在其他高级语言中称为记录(record) ...

  3. C语言链表结构体(学习笔记)

    #include <stdio.h> #define LENTEST 100 // 采取逐步删除的方法求的素数 //先假设1-100都是素数,然后剔除2的倍数, //3的倍数,直到剔除所有 ...

  4. C语言中结构体对齐问题

    C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...

  5. C语言中结构体赋值问题的讨论

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

  6. C语言的结构体和C++结构体的区别

    关于C++中声明结构体中需要使用构造器创建实例对象的语法: <C++的结构体构造方法的基本概念:结构体的构造方法需要和结构体的名字相同,并且无返回值,也不要void关键字,这样的方法就是构造器的 ...

  7. 逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式

    逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式 一丶了解什么是结构体,以及计算结构体成员的对其值以及总大小(类也是这样算) 结构体的特性 1.结构体(struct)是由一系列具有相同类型或不 ...

  8. C语言中结构体赋值问题的讨论(转载)

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

  9. go语言学习-结构体

    结构体 go语言中的结构体,是一种复合类型,有一组属性构成,这些属性被称为字段.结构体也是值类型,可以使用new来创建. 定义: type name struct { field1 type1 fie ...

  10. 将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. ...

随机推荐

  1. FTP服务器中文环境引起润日下载不了附件问题解析

    20160229日某农商行因为FTP下载功能有问题,导致当天所有涉及FTP文件下载的交易都不能正常使用,对于银行来说影响还是比较大.现将当天出问题的原因及处理过程解析如下,忘能给碰到类似问题的同行以供 ...

  2. 2012蓝桥杯本科组C/C++决赛题

    星期几 [结果填空] (满分5分) 1949年的国庆节(10月1日)是星期六. 今年()的国庆节是星期一. 那么,从建国到现在,有几次国庆节正好是星期日呢? 只要答案,不限手段! 可以用windows ...

  3. apt局域网源搭建

    1, 准备Packages.gz

  4. Angular过滤器 自定义及使用方法

    首先设置自定义过滤器. 定义模块名:angular .module('myApp') .filter('filterName',function(){ return function(要过滤的对象,参 ...

  5. AABB包围盒、OBB包围盒、包围球的比較

    1) AABB 包围盒: AABB 包围盒是与坐标轴对齐的包围盒, 简单性好, 紧密性较差(尤其对斜对角方向放置的瘦长形对象, 採用AABB, 将留下非常大的边角空隙, 导致大量不是必需的包围盒相交測 ...

  6. yii columns value and type and checkbox columns

    value  I am here type  I am here checkbox columns   useage

  7. codevs 1725 探险 (二分)

    /* 二分答案 这个题目要求“体力和最小的那个小组的所有人的体力和尽量大” 很明显我们二分最小体力 如果合法 逐渐放大 但是这里我们二分的是最小而不是最大 所以累加的体力>=ans时 跳过当前体 ...

  8. 在imge控件中直接显示图片(图片是byte[]格式)

    在工作过程中遇到了这个问题,在网上查了一些资料,结合自己的解决方法及解决过程总结了下,方面以后查阅.如果能帮到同样遇到这个问题的你,将非常高兴哦~_~ 由于asp.net中的Image控件是在Syst ...

  9. .NET获取机器信息

    /// <summary> /// using System.Web; /// using System.Management; /// </summary> public s ...

  10. 各浏览器对 onbeforeunload 事件的支持与触发条件实现有差异

    转载:http://www.w3help.org/zh-cn/causes/BX2047 标准参考 无. 问题描述 一般情况下,onbeforeunload 事件处理函数内会写入一些提示性语句,当用户 ...