当前位置: 首页 > article >正文

【C语言】结构体大小计算

一.如何计算结构体大小

对齐基本规则:

1.结构体的第一个成员对齐到结构体变量起始位置偏移量为0的地址处;

 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的偏移量的地址处(对齐数 = 编译器默认的对齐数 与 该成员变量大小的较小值,VS 中默认的值为 8);

  3.结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍;

    

针对嵌套结构体的附加规则:

如果嵌套了结构体,嵌套的结构体对齐到自身的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体所有成员的对齐数)的整数倍

1.普通结构体

遵循基本规则

解题步骤

(1)找出对齐数

找出每个成员变量的大小将其与编译器的默认对齐数相比较,取其较小值为该成员变量的对齐数

(2)画图

遵循基本规则为每个成员画出它们在内存中的相对位置,确定大小。

综上,当前struct大小为16.

验证:

2.包含数组成员的结构体

将数组直接拆开当做普通成员

解题步骤

(1)确定对齐数

(2)画图

原结构体计算大小时等价于:

综上,struct X大小为20

验证:

3.嵌套结构体的结构体

遵循基本规则+附加规则

解题步骤

(1)确定对齐数

求struct X大小。

(2)画图

综上,struct S长度为20.

验证:

总结:计算嵌套结构体成员的结构体大小时,提前算出嵌套结构体的大小,按照附加规则对齐即可

二.如何修改默认对齐数 

#pragma pack(n)

每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。

示例:

将默认对齐数改为4.

#pragma pack(4)

struct node{

  int e;
  char f;
  short int a;
  char b;

};

struct node n;

printf("%d\n",sizeof(n));

结果:

三.如何查看结构体成员地址偏移量

我们学习结构体的时候,我们知道,结构体中的元素不一定是紧密排列的,其中有对其数和偏移量,那么有没有什么方法能直接输出某个元素的偏移量呢?答案是有的,我们只需要使用offsetof宏即可。

1.什么是offsetof宏

offsetof宏的作用是获取结构体中某个成员相对于结构体起始地址的偏移量。通过计算成员在结构体中的位置,它提供了一种可移植的方法来确定偏移量。

原型:

offsetof(type, member)

参数说明:

  • TYPE: 表示结构体或联合体的类型名。当你需要计算某个结构体类型中某个成员的偏移量时,应在此处指定该结构体类型。

  • MEMBER: 表示结构体(或联合体)中需要计算偏移量的成员名称。这是你希望得知其在结构体内部位置的字段。

返回值:

该宏返回类型为 size_t 的值,表示 type 中成员的偏移量。

2.offsetof宏的使用

举例说明:

#include<stdio.h>
#include<stddef.h>
struct ST
{
	char a;
	int b;
	float c;
};
int main()
{
	printf("%zd\n", offsetof(struct ST, b));
	printf("%zd\n", offsetof(struct ST, c));
	return 0;
}

3.offsetof宏的自我实现

#define MY_offsetof(S,m) (size_t) &(((S*)0)->m)
  • ((S *)0):  取整数零并将其转换为指向 S 的指针。
  • ((S *)0)->m: 引用指向结构成员 m 的指针。
  • &(((S *)0)->m):计算 m 的地址。
  • (size_t)&(((S *)0)->m): 将结果转换为适当的数据类型。

代码示例:

#include<stdio.h>
#define MY_offsetof(S,m) (size_t)&(((S*)0)->m)
 
struct ST
{
	char a;
	int b;
	float c;
};
int main()
{
	printf("%zd\n", MY_offsetof(struct ST, b));
	printf("%zd\n", MY_offsetof(struct ST, c));
	return 0;
}

运行结果:


http://www.kler.cn/a/391875.html

相关文章:

  • 限流算法(令牌通漏桶计数器)
  • python高效处理大数据:将Excel10万数据分批插入MySQL数据库的实战代码
  • Electron 项目启动外部可执行文件的几种方式
  • 使用Python实现定期从API获取数据并存储到数据库的完整指南
  • Web安全之SQL注入---基础
  • 软件测试面试八股文(超详细整理)
  • 机器学习、深度学习面试知识点汇总
  • 三星手机投屏到MacBook的方法,多台手机同屏展示
  • 【MyBatis源码】SQL 语句构建器AbstractSQL
  • 第二届无人驾驶与智能传感技术国际学术会议
  • 青藤深度参编的终端安全国家标准正式发布
  • 怎么保护源代码,源代码防泄密的十种方法
  • Spring Boot编程训练系统:从概念到实现
  • 用 Python 从零开始创建神经网络(一):编码我们的第一个神经元
  • python + requests实现的接口自动化测试
  • 我的 Rust 之旅,以及如何学习 Rust
  • 十八:Spring Boot 依赖(3)-- spring-boot-starter-data-jpa 依赖详解
  • react-markdown标题样式不生效问题
  • 视频会议接入GB28181视频指挥调度,语音对讲方案
  • HTML(超文本标记语言)
  • 中介者设计模式 软考
  • Python毕业设计选题:基于django+vue的论坛BBS系统
  • RBF 网络的学习算法:原理、实现与应用
  • WebPages 安全
  • 用单片机MSP430设计一个太阳能实战项目,能够详细的设计出它的硬件和软件系统
  • matlab实现主成分分析方法图像压缩和传输重建