【自定义类型】(结构体、枚举、联合)

结构体内存对齐:

计算结构体的大小

结构体成员不是按照顺序在内存中连续存放的而是有一定的对齐规则的

结构体内存对齐的规则:

1、结构体的第一个成员永远放在相比于结构体变量起始位置的偏移量为0的位置。

2、从第二个成员开始,往后的每个成员都要对齐到某个对齐数的整数倍处。对齐数:结构体成员自身的大小和默认对齐数的较小值。在VS环境上的默认对齐数是8,在gcc(Linux)环境上没有默认对齐数,对齐数就是结构体成员的自身大小。

3、结构体的总大小必须是最大对齐数的整数倍(最大对齐数是所有成员的对齐数中的最大的值)

4、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍


offsetof
对应的头文件是:#include <stddef.h>
可以计算结构体成员相较于结构体起始位置的偏移量

#include <stddef.h>
#include <stdio.h>

struct S1
{
	char c1;//1
	int i;//4
	char c2;//1
};
//0 - 1
//1 2 3 (4 5 6 7) - 4
//8 - 1
//0 - 8 - 9个空间单元 但是不是4的整数倍
//10 11 12是4的整数倍
//12

struct S2
{
	int i;//4
	char c1;//1
	char c2;//1
};
//0 1 2 3 - 4
//4 - 1
//5 - 1
//0 - 5 6个存储空间单元 但是不是4的整数倍
//7 8是4的整数倍
//8

int main()
{
	struct S1 s1 = { 0 };

	printf("%d\n", sizeof(struct S1));//12
	printf("%d\n", sizeof(struct S2));//8

	printf("%d\n", offsetof(struct S1, c1));//可以计算结构体成员相较于结构体起始位置的偏移量
	printf("%d\n", offsetof(struct S1, i));
	printf("%d\n", offsetof(struct S1, c2));

	printf("%d\n", offsetof(struct S2, i));
	printf("%d\n", offsetof(struct S2, c1));
	printf("%d\n", offsetof(struct S2, c2));
	return 0;
}

#include <stdio.h>

struct S3
{
	double d;
	char c;
	int i;
}; 
//0 - 7 - 8个
//8 - 1个
//9 10 11 (12 13 14 15) - 4个
//0 - 15 是16个空间刚好是8的整数倍
//16

struct S4
{
	char c1; // 1
	struct S3 s3; // 8 大小空间为16
	double d; // 8
};
//0 - 1个位置
//第二个是结构体:其对应的最大对齐数是8,移到8的位置开始
//这个结构体的总共大小为16,所以从8开始到23放这个结构体
//然后24开始到31存放第三个元素
//总共0-31是32个空间大小
//32 刚好32也是8的整数倍

int main()
{
	printf("%d\n", sizeof(struct S3));
	printf("%d\n", sizeof(double));//8
	printf("%d\n", sizeof(float));//4

	printf("%d\n", sizeof(struct S4));//32

	return 0;
}

在这里插入图片描述


如果说遇到数组作为结构体的元素:
int a[3];可以直接看作3个整型元素存放进去

总体来说:结构体的内存对齐是拿空间来换取时间


我们可以通过让占用空间小的成员尽量集中在一起

struct S1
{
	char c1;//1
	int i;//4
	char c2;//1
};//12

struct S2
{
	int i;//4
	char c1;//1
	char c2;//1
};//8

修改默认对齐数:
使用 #pragma

#pragma pack(8) //设置默认对齐数为8
#pragma pack()  //取消设置的默认对齐数,还原为默认
#pragma pack(1)
//默认对齐数为1
struct S
{
	char c1;//1 1 1
	int a; // 4 1 1
	char c2;//1 1 1
};

#pragma pack()

int main()
{
	printf("%d\n", sizeof(struct S));//6
	return 0;
}

位段
1、位段的成员必须是:int、unsigned int 或者 signed int(char也是属于整型家族的
2、位段的成员名后边有一个冒号和一个数字

struct A
{
	int _a : 2;//二进制位
	int _b : 5;
	int _c : 10;
	int _d : 30;
	//总共需要47个二进制位
	//1个int是32位
	//2个int是8个字节
};

int main()
{
	printf("%d\n", sizeof(struct A));//8

	return 0;
}
struct S
{
	char a : 3;
	//3个比特位 先给你一个字节
	char b : 4;
	//4个比特位
	char c : 5;
	//5个比特位 需要再去申请一个字节
	char d : 4;
	//4个比特位 需要再去申请一个字节
};
int main()
{
	struct S s = { 0 };
	s.a = 10;
	s.b = 12;
	s.c = 3;
	s.d = 4;
	printf("%d\n", sizeof(s));//3
	return 0;
}

枚举enum


联合(共用体)union

联合的成员是共用同一块内存空间的,这样的一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

联合体大小的计算:联合体的大小至少是最大成员的大小

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

//判断大小端存储方式
int check_sys()
{
	union
	{
		int i;
		char c;
		//使用同一块空间
	}un = {.i = 1};
	return un.c;
	//01 00 00 00 小端
	//00 00 00 01 大端
}

int main()
{
	int ret = check_sys();
	

	if (ret == 1)
		printf("小端\n");//小端存储方式
	else
		printf("大端\n");

	return 0;
}
union Un1
{
	char c[5];//(5) 1 8 (1)
	int i;//(4) 8 (4)
};
//5 为了凑成4的整数倍 所以为8

union Un2
{
	short c[7];//(14) 2 8 (2)
	int i;//(4) 4 8 (4)
};
//14为了凑成4的整数倍 所以为16

int main()
{
	printf("%d\n", sizeof(union Un1));//5+3 = 8
	printf("%d\n", sizeof(union Un2));//16

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Gateway服务集成Nacos2021.0.4错误解决

问题 gateway服务集成nacos&#xff0c;启动后报错&#xff1a; Caused by: com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information:; 版本&#xff1a; jdk:1.8 spring-b…

Node连接Mongodb数据库

1.初始化 npm init 2.安装mongoose npm i mongoose 3.导入mongoose const mongooserequire("mongoose") 4.连接mongodb服务 mongoose.connect("mongodb://127.0.0.1:27017/user") 说明&#xff1a;mongodb是协议,user是数据库&#xff0c;如果没有会自动创…

C#使用跨平台的PdfSharpCore开源库生成PDF文件

一、需求说明 在进行项目开发中,需要将C#程序的一些文本内容导出为PDF文件(能够根据文本自动分行分页),并且要求这个生成PDF文件的程序是可跨平台的;实现类似效果: 二、需求分析 ①将程序的文本内容导出为PDF文件; ②能够将文本内容自动分行分页【且可添加页眉、页脚、…

Docker安全开放远程访问连接权限

1、Docker完全开放远程访问 Docker服务完全开放对外访问权限操作如下&#xff1a; # 开启端口命令 &#xff08;--permanent永久生效&#xff0c;没有此参数重启后失效&#xff09; firewall-cmd --zonepublic --add-port2375/tcp --permanent # 重新载入 firewall-cmd --re…

2.Vue3中Cesium地图初始化及地图控件配置

前言 本文中&#xff0c;我们主要介绍 Cesium 在 Vue 3运行环境的配置&#xff0c;以及 Cesium 实例中控件的显隐设置&#xff0c;本文是后续文章内容的基础&#xff0c;项目代码在此查看&#xff1b;通过本文&#xff0c;我们可以得到一个纯净的 cesium 项目&#xff0c;后续的…

字符设备驱动开发(最初方式)

目录&#xff1a; 1.字符设备驱动简介2.字符设备驱动开发步骤2.1. 驱动模块的加载与卸载2.2. Makefile的编写2.3.字符设备的注册与注销2.3.1.设备号的组成2.3.2.设备号的分配 2.4.具体操作函数的实现2.4.1.进行打开和关闭操作2.4.2.对chrdev进行读写操作 3.具体程序的实现3.1.驱…

huggingface datasets map时出现KeyError: ‘output‘的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Spring MVC相关注解运用 —— 上篇

目录 一、Controller、RequestMapping 1.1 示例程序 1.2 测试结果 二、RequestParam 2.1 示例程序 2.2 测试结果 三、RequestHeader、CookieValue 3.1 示例程序 3.2 测试结果 四、SessionAttributes 4.1 示例程序 4.2 测试结果 五、ModelAttribute 5.1 示例程序 …

IDEA+springboot+mybatis+shiro+bootstrap+Mysql WMS仓库管理系统

IDEAspringbootmybatisshirobootstrapMysql WMS仓库管理系统 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.修改密码3.系统日志4. 登陆日志5. 库存查询6. 出入库记录7.货物入库8.货物出库9.仓库管理员管理10.供应商信息管理11.客户信息管理12.货物信息管理13. 仓库信息管…

Prometheus学习

Prometheus学习 promethueus exporter就是以 后台进程的方式运行在系统当中&#xff0c;不断去采集数据 1、红框框中是 prometheus基于数学算法输入的一个查询输入框 2.监控项的分类 3.数据采集的形式分类&#xff08;promethueus exporter就是以 后台进程的方式运行在系统当…

最新2023水果编曲软件FL Studio Producer Edition 21.0.3 Build 3517中文版下载安装激活图文教程

各位&#xff0c;大家好&#xff0c;今天兔八哥给大家带来最新最新2023水果编曲软件FL Studio Producer Edition 21.0.3 Build 3517中文版下载安装激活图文教程。我们一起先了解一些FL Studio 。FL Studio21是目前流行广泛使用人数最多音乐编曲宿主制作DAW软件&#xff0c;这款…

17.OpenCV中的GFTTDetector类

文章目录 GFTTDetector功能OpenCV中GFTTDetector类reference 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; 这是使用imgproc.hpp中的goodFeaturesToTrack函数封装的类&#xff0c;其使用和goodFeaturesToTrack函数基本相似。 GFTTDetec…

Hyperledger Fabric测试网络的准备和基本使用

文章目录 相关安装启动测试网络创建channel打包链码安装链码包通过链码定义链码定义提交给通道调用链码关闭网络遇到的问题1.docker保持启动状态2.忘起测试网络了3.Java版本过高&#xff0c;推荐1.8 相关安装 npm、node、git、docker、docker-compose。docker保证一直运行 serv…

[Error] invalid preprocessing directive #inclued问题解决

错误代码 报错内容 [Error] invalid preprocessing directive #inclued 错误原因 #inclued写错了应该写成#include

flutter页面添加透明遮罩

路由工具 import package:test/main.dart; import package:flutter/material.dart;import circle_page_route.dart;class NavigatorUtil {static push(Widget page, {BuildContext context}) {return Navigator.push(context ?? navigatorKey.currentContext,MaterialPageRo…

HTTP以及Servlet的学习

HTTP和Servlet 联系&#xff1a; HTTP是一个通信协议&#xff0c;而Servlet是服务器端程序&#xff0c;用于处理HTTP请求。Servlet通常用于处理HTTP请求&#xff0c;在服务器上生成动态内容&#xff0c;并生成HTTP响应。HTTP协议就是Servlet处理的基础。 区别&#xff1a; …

Matlab数学建模实战——(Lokta-Volterra掠食者-猎物方程)

1.题目 问题1 该数学建模的第一问和第二问主要是用Matlab求解微分方程组&#xff0c;直接编程即可。 求解 Step1改写 y(1)ry(2)f Step2得y的导数 y(1).2y(1)-ay(1)*y(2)y(2).-y(2)a*y(1)*y(2) Step3编程 clear; a0.01; F(t,y)[2*y(1)-a*y(1)*y(2);-y(2)a*y(1)*y(2)]; […

MySQL的数据备份与还原--练习题

MySQLdump MySQLdump是MySQL提供的一个非常有用的数据库备份工具。MySQLdump命令执行时&#xff0c;可以将数据库备份成一个文本文件&#xff0c;该文件中实际上包含了多个CREATE 和 INSERT语句&#xff0c;使用这些语句可以重新创建表和插入数据。 看题&#xff1a; 第一题&a…

【新手上路】如何在Web3时代成为XR创建者

目录 0 XR在Web3里的作用 1 XR的概念、特征、技术、设备、平台、应用和工具 1.1 VR的概念、特征和技术 1.2 AR的概念、特征和技术 1.2 XR的设备、平台、应用和工具 2 选择XR的方法 2.1 何时使用VR 2.2 何时使用AR 3 开发XR作品的4个步骤 4 成为XR构建者的路径 4.1 三…

Win10使用gdc-client下载TCGA数据集【安装使用教程】成功解决闪退问题!

做实验需要下载TCGA数据集&#xff0c;数据量比较大的时候&#xff0c;直接从网页下载速度非常慢&#xff0c;容易出现下载不全等情况。 调研后选择在Win10端使用gdc-client来帮助下载Cart文件。 一、下载软件、配置环境 下载软件 下载网站链接&#xff1a;https://gdc.can…