offsetof宏的使用、模拟实现及 (size_t)(((struct_type*)0)->mem_name)的解释

宏原型:offsetof(type,member)

作用:返回数据结构或联合体类型中成员的偏移量,以字节为单位

返回值:size_t类型的无符号整数

使用案例:

#include <stdio.h>    
#include <stddef.h>   struct foo {char a;char b[10];char c;
};int main()
{printf("offsetof(struct foo,a) is %d\n", (int)offsetof(struct foo, a));printf("offsetof(struct foo,b) is %d\n", (int)offsetof(struct foo, b));printf("offsetof(struct foo,c) is %d\n", (int)offsetof(struct foo, c));return 0;
}

模拟实现:

#include <stdio.h>
//写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明
struct Stu
{int a;char c;double d;
};#define OFFSETOF(struct_type, mem_name)      (size_t)&(((struct_type*)0)->mem_name)
//这样的强制类型转换应该使用 (size_t) 而不是 (int) 
//为了确保能够存储较大范围内的偏移值int main()
{printf("%d\n", OFFSETOF(struct Stu, a));printf("%d\n", OFFSETOF(struct Stu, c));printf("%d\n", OFFSETOF(struct Stu, d));return 0;
}

关于“(size_t)&(((struct_type*)0)->mem_name)”的解释:

        该表达式的作用是用于获取结构体成员相对于结构体在内存中的偏移量,它将 0 强制类型转换为指向 struct_type 类型的空指针,获取结构体中成员的地址后再强制转换为无符号整型size_t。

注意事项:

  1. 这种技巧通常用于底层编程或者涉及到直接操作内存布局和字节对齐等细节时。一般情况下,在正常应用程序开发过程中不建议频繁使用此类技巧。
  2. 在实际应用时,请确保遵循相关语言和平台规范,并小心处理可能出现未定义行为或错误结果的情况。

关于“(struct_type*)0”的解释:

        在 C 和 C++ 中,整数 0 可以被隐式地转换为空指针。

注意事项:在实际应用中,并不推荐将整数 0 直接强制转换为空指针。根据 C 和 C++ 的规范,在大多数情况下,应该使用 NULL 或 nullptr 来表示空指针。

关于将地址强制类型转换为size_t类型后如何获取偏移量的解释: 

#include <stdio.h>
typedef struct {int member1;char member2;double member3;
} MyStruct;int main() {MyStruct myStruct;// 获取成员变量的地址int* ptr_member1 = &myStruct.member1;char* ptr_member2 = &myStruct.member2;size_t member1 = ptr_member1;size_t member2 = ptr_member2;size_t all = &myStruct;printf("%u\n", all);printf("%u\n", member1);printf("%u\n", member2);return 0;
}

        在这里我们获取了结构体本身地址强制类型转换为size_t后的值2845767320,以及它的两个成员强转后的值2845767320和2845767324,我们可以发现貌似只需要对这些值进行简单的减法运算就可以得到结构体每个成员相对于结构体在内存上的偏移量,但是我们发现关于#OFFSETOF自定义宏包括主函数中并未提及减法操作,但还是得到了相应的偏移量,这是因为:编译器在处理空指针时会有隐式行为:在获取结构体成员地址时,默认情况下编译器会计算出从起始位置(即空指针)到该成员之间的偏移量。然后就该偏移量被强制类型转换为size_t型输出......

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/133115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jenkins展示html报告样式需要注意的要点

一、jenkins展示html报告样式需要注意的要点 最后&#xff1a;

使用Kotlin与Unirest库抓取音频文件的技术实践

目录 摘要 一、Kotlin与Unirest库概述 二、使用Kotlin和Unirest抓取音频文件 1、添加Unirest依赖 2、发送HTTP请求获取音频文件 3、保存音频文件 三、完整代码示例 四、注意事项 结论 摘要 本文详细阐述了如何使用Kotlin编程语言与Unirest库抓取网络上的音频文件。首…

NSSCTF第11页(1)

[HUBUCTF 2022 新生赛]Calculate 进到主页 翻译 回答以下数学问题20次&#xff1b;你有3秒钟的时间来解决每个问题&#xff1b; 为了保护服务器&#xff0c;你不能在1秒内回答一个问题 您已回答0个问题&#xff1b; 让我们3秒速算&#xff0c;没那个实力&#xff0c;提示说是写…

DockerFile常用保留字指令及知识点合集

目录 DockerFile加深理解&#xff1a; DockerFile常用保留字指令 保留字&#xff1a; RUN&#xff1a;容器构建时需要运行的命令 COPY&#xff1a;类似ADD&#xff0c;拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 …

微信小程序之自定义组件开发

1、前言 从小程序基础库版本 1.6.3 开始&#xff0c;小程序支持简洁的组件化编程。所有自定义组件相关特性都需要基础库版本 1.6.3 或更高。开发者可以将页面内的功能模块抽象成自定义组件&#xff0c;以便在不同的页面中重复使用&#xff1b;也可以将复杂的页面拆分成多个低耦…

3D 线激光相机的激光条纹中心提取方法

论文地址:Excellent-Paper-For-Daily-Reading/application/centerline at main 类别:应用——中心线 时间:2023/11/06 摘要 线激光条纹中心提取是实现线激光相机三维扫描的关键,根据激光三角测量法研制了线激光相机,基于传统 Steger 法对其进行优化并提出一种适用于提…

爱上C语言:函数递归,青蛙跳台阶图文详解

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;生活本来沉闷&#xff0c;但跑起来就有风 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请…

数据的备份和恢复

数据的备份和恢复 备份&#xff1a;完全备份 增量备份 完全备份&#xff1a;将整个数据库完整的进行备份 增量备份&#xff1a;在完全备份的基础之上&#xff0c;对后续新增的内容进行备份 备份的需求 1、在生产环境中&#xff0c;数据的安全至关重要、任何数据的丢失都可…

​软考-高级-信息系统项目管理师教程 第四版【第16章-项目采购管理-思维导图】​

软考-高级-信息系统项目管理师教程 第四版【第16章-项目采购管理-思维导图】 课本里章节里所有蓝色字体的思维导图

Ubuntu 创建用户

在ubuntu系统中创建用户&#xff0c;是最基本的操作。与centos7相比&#xff0c;有较大不同。 我们通过案例介绍&#xff0c;讨论用户的创建。 我们知道&#xff0c;在linux中&#xff0c;有三类用户&#xff1a;超级管理员 root 具有完全权限&#xff1b;系统用户 bin sys a…

Hello Qt!

目录 1. 什么是Qt 2. Qt中的模块 3. 下载安装 4. QtCreator 4. Hello Qt 解释 .pro 解释 main.cpp 解释 mainwindow.ui 解释 mainwindow.h 解释 mainwindow.cpp 5. Qt 中的窗口类 5.1 基础窗口类 5.2 窗口的显示 6. Qt 的坐标体系 7. 内存回收 1. 什么是Qt 是一…

图片怎么转换成pdf?

图片怎么转换成pdf&#xff1f;图片可以转换成PDF格式文档吗&#xff1f;当然是可以的呀&#xff0c;当图片转换成PDF文件类型时&#xff0c;我们就会发现图片更加方便的打开分享和传播&#xff0c;而且还可以更加安全的保证我们的图片所有性。我们知道PDF文档是可以加密的&…

树莓派在Raspbian系统(Bookworm)中无法获取RJ45网口eth0或end0的IP地址(没有IPv4的地址无法操作)

由于 Raspbian 上个月刚好从 Bullseye 升级到 Bookworm 版本了&#xff0c;所以出现了很多修改&#xff0c;截止写博客的时候过去还没三十天&#xff0c;当然也没那么多解决方案参考&#xff0c;只能参考之前版本或者靠自己了&#xff0c;未来或许官方会进行修复&#xff0c;也…

04-SpringBoot的基础配置及其配置文件分类,解决Yaml文件失效问题

SpringBoot的配置 SpringBoot是用来提高Spring程序的开发效率的,使用SpringBoot后几乎不用做任何配置功能就有了,因为很多功能已经有默认配置帮我们做好了 配置文件的相关配置 在一个项目中不同的技术对应不同的配置文件并且这些配置文件的格式也不统一 SpringBoot提供了一…

x86汇编代码学习-计算机工作原理1

文章目录 前言1.CPU架构2.8086寄存器3. 指令流水线4.内存模型5.总线6.硬盘7 计算机启动过程BIOS8.BootLoader9.地址映射10.为什么boot loader要放在0x7c00这个位置&#xff1f;11 显卡是如何显示的12.汇编指令1.环境搭建 12 程序13 x86 汇编指令介绍 前言 x86汇编 详解x86汇编…

设计模式—结构型模式之桥接模式

设计模式—结构型模式之桥接模式 将抽象与实现解耦&#xff0c;使两者都可以独立变化。 在现实生活中&#xff0c;某些类具有两个或多个维度的变化&#xff0c;如图形既可按形状分&#xff0c;又可按颜色分。如何设计类似于 Photoshop 这样的软件&#xff0c;能画不同形状和不…

R语言 PPT 预习+复习

什么狗吧发明的结业考&#xff0c;站出来和我对线 第一章 绪论 吊码没有&#xff0c;就算考R语言特点我也不背&#xff0c;问就是叫么这没用。 第二章 R语言入门 x<-1:20 赋值语句 x 1到20在x上添加均值为0、标准差为2的正态分布噪声 y <- x rnorm (20, 0, 2) 这…

【Matplotlib】plt.plot() X轴横坐标展示完整整数坐标

比如说&#xff0c;我的数据应该是 x轴从2到21的20个整数 y轴对应值 但是直接plot的话x轴显示居然有小数点什么鬼 可以这样改

2022年电工杯数学建模B题5G网络环境下应急物资配送问题求解全过程论文及程序

2022年电工杯数学建模 B题 5G网络环境下应急物资配送问题 原题再现&#xff1a; 一些重特大突发事件往往会造成道路阻断、损坏、封闭等意想不到的情况&#xff0c;对人们的日常生活会造成一定的影响。为了保证人们的正常生活&#xff0c;将应急物资及时准确地配送到位尤为重要…

二十、泛型(2)

本章概要 泛型接口泛型方法 变长参数和泛型方法一个泛型的 Supplier简化元组的使用一个 Set 工具 泛型接口 泛型也可以应用于接口。例如 生成器&#xff0c;这是一种专门负责创建对象的类。实际上&#xff0c;这是 工厂方法 设计模式的一种应用。不过&#xff0c;当使用生成…