前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >数据结构类型(内存篇)

数据结构类型(内存篇)

作者头像
木杉乀
发布于 2021-04-01 22:35:23
发布于 2021-04-01 22:35:23
70200
代码可运行
举报
文章被收录于专栏:木杉の小屋木杉の小屋
运行总次数:0
代码可运行

数据结构类型(内存篇)超全结构体,联合,枚举内存解释(适用c语言入门)

一.结构体的内存

内存对齐

规则:

1.结构体的第一个数据成员存放的地址为结构体变量偏移量为 0 的地址处.

2.其他起始地址为该类型变量所占内存的整数倍,如果不足部分用数据填充到所占内存的整数倍

3.结构体所占总内存为该结构体的成员中基本数据类型占字节数最大的整数倍

(见图解1-1)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include

struct str1 {   // ??
	char a;     //  1 byte  //此处若删除char a 则所占内存为 24 以验证规则 1;(自行验证)
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
	char ch;    //  1 byte
}s1;            // 32 byte

//将结构体内部变量调换位置后结构体内存占用发生改变

struct str2 {   // ?? 
	char a;     //  1 byte
	char ch;    //  1 byte
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
}s2;            // 24 byte

int main() {
	printf("%d\n",sizeof(s1));  //输出结果:32
	printf("%d\n",sizeof(s2));  //输出结果:24
	return 0;
}
图解1-1

如果结构体内部含有数组:(见图解1-2)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include

// 当结构体成员包含数组:
struct str3 {
	int a;       //  4 byte
	double b;    //  8 byte(最大)  
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s3;             //  结果:32

struct str4 {
	double b;    //  8 byte(最大)
	int a;       //  4 byte
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s4;             //  结果:24

int main() {
	//如果结构体成员含有数组:
	printf("%d\n", sizeof(s3));  //输出结果:32
	printf("%d\n", sizeof(s4));  //输出结果:24
	return 0;
}
图解1-2

如果结构体中包含结构体:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include

struct str5 {
	char ch;
	short sh;
	int num;
}s5;

struct str6 {
	int n;
	struct str5 s5;
}s6;

struct str7 {
	int n;
	char ch;
	short sh;
	int num;
}s7;

int main() {
	//如果结构体成员包含结构体:
	printf("%d\n", sizeof(s5));  //输出结果:8
	printf("%d\n", sizeof(s6));  //输出结果:12 --> sizeof(int)+8
	printf("%d\n", sizeof(s7));  //输出结果:12
	return 0;
}

结论:结构体 str6 和 str7等价,当结构体中成员包含结构体时 等价于 把成员结构体内容展开

注意:结构体成员包含的结构体不能为本身!

[完整代码如下]
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include

struct str1 {   //  内部求和为 18byte
	char a;     //  1 byte
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
	char ch;    //  1 byte
}s1;            //  结果:32 byte

// 将结构体成员变量调换位置后结构体内存占用发生改变:
struct str2 {   //  内部求和为 18byte
	char a;     //  1 byte
	char ch;    //  1 byte
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
}s2;            //  结果:24 byte

// 当结构体成员包含数组:
struct str3 {
	int a;       //  4 byte
	double b;    //  8 byte(最大)  
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s3;             //  结果:32

struct str4 {
	double b;    //  8 byte(最大)
	int a;       //  4 byte
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s4;             //  结果:24

// 当结构体成员包含结构体:
struct str5 {
	char ch;
	short sh;
	int num;
}s5;

struct str6 {
	int n;
	struct str5 s5;
}s6;

struct str7 {
	int n;
	char ch;
	short sh;
	int num;
}s7;

int main() {

	printf("%d\n",sizeof(s1));  //输出结果:32
	printf("%d\n",sizeof(s2));  //输出结果:24
	printf("\n");
	//如果结构体成员含有数组:
	printf("%d\n", sizeof(s3));  //输出结果:32
	printf("%d\n", sizeof(s4));  //输出结果:24
	printf("\n");
	//如果结构体成员包含结构体:
	printf("%d\n", sizeof(s5));  //输出结果:8
	printf("%d\n", sizeof(s6));  //输出结果:12
	printf("%d\n", sizeof(s7));  //输出结果:12
	return 0;
}

二.联合体的内存

规则:

1.大小必须足够容纳最宽的成员 2.大小能够被它所包含的所有的基本数据类型的大小整除

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include

union MyUnion1{
	char s[9];     //  9 byte (char类型为 1 byte)
	int n;         //  4 byte
	double d;      //  8 byte
};                 // 16 byte

union MyUnion2 {
	char s[5];     //  5 byte
	int n;         //  4 byte
	double d;      //  8 byte
};                 //  8 byte
int main() {
	printf("%d\n", sizeof(MyUnion1));     // 结果:16
	printf("%d\n", sizeof(MyUnion2));     // 结果:8
}

三.枚举的内存

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include

enum Enum {
	Enum1,      // (int) 4 byte
	Enum2,      // (int) 4 byte
	Enum3       // (int) 4 byte
}MyEnum;

int main() {
	printf("%d\n", sizeof(MyEnum));  // 结果:4
	printf("%d\n", sizeof(Enum1));   // 结果:4
	printf("%d\n", sizeof(Enum2));   // 结果:4
	printf("%d\n", sizeof(Enum3));   // 结果:4
	return 0;
}

关于枚举的解释大多数为:枚举皆为4字节;(例:如上情况)

——关于枚举内存的问题不必太深究,但是想探一探。

标准C语言描述没有明确规定枚举类型占用空间的大小,表示:“枚举类型的尺寸是以能够容纳最大枚举子值的整数的尺寸”,同时标准中也说明了: “枚举类型中的枚举子的值必须 能够 用一个int类型表述.”

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include

enum Enum {
	Enum1 = 0x7f7f7f7f7f,    // (int类型最大值) (int) 4 byte
	Enum2,                   //               (int) 4 byte
	Enum3,                   //               (int) 4 byte
	Enum4 = 5,
	Enum5,
    Enum6 = 0x7f7f7f7f7f,    //(int类型最大值)
	Enum7
}MyEnum;

int main() {
	printf("%d\n", sizeof(MyEnum));  // 结果:8
	printf("%d\n", sizeof(Enum1));   // 结果:8
	printf("%d\n", sizeof(Enum2));   // 结果:8
	printf("%d\n", sizeof(Enum4));   // 结果:4
    printf("%d\n", sizeof(Enum5));   // 结果:4
    printf("%d\n", sizeof(Enum6));   // 结果:8
    printf("%d\n", sizeof(Enum7));   // 结果:8
	return 0;
}

当枚举子值超过 int 范围时 得到枚举字节占用为 8 byte

本以为是枚举定义为 long 类型尺寸,但是发现子值的输出并非正确数值输出,依旧溢出;

此处可能与 int 类型的大小有关:

(关于 int 类型)其大小为计算机的字长,与cpu寄存器位数相关

一般情况:32位计算机为4字节 64位计算机为8字节

但在 x64 计算机环境调试结果多数仍然为4字节可能和编译器等多方面条件有关。

搜索资料中发现这样一篇文章:https://blog.csdn.net/HES_C/article/details/88668276

按照c语言描述可以实现,但本人未能实现。查询整理得到另一些合理解释:

具体内容如下:

1.转载:https://embedded.fm/blog/2016/6/28/how-big-is-an-enum

2.来自知乎留言:

enum本身并不以变量的方式存储到内存当中,但是将enum本身作为变量(包括指定具体是哪个枚举值),因为这个变量包含了枚举类型中的一部分值,所以会分配空间,这个具体值的大小,应该和机器、枚举值指定值有关系。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
详解自定义类型:结构体,位段,枚举,联合
我们已经掌握了结构体的基本使用了。 现在我们深入讨论一个问题:计算结构体的大小。 这也是一个特别热门的考点: 结构体内存对齐
用户11369558
2024/11/20
1390
详解自定义类型:结构体,位段,枚举,联合
C语言进阶—自定义类型:结构体,枚举,联合
struct Student { char name[20]; int age; char sex[5]; float score; } s1, s2, s3;//s1, s2, s3 是三个结构体变量 - 全局变量
小李很执着
2024/06/15
1100
C语言进阶—自定义类型:结构体,枚举,联合
C语言自定义数据类型
结构体 参考视频:https://www.bilibili.com/video/BV1oi4y1g7CF?p=58 大纲: 结构体的声明 结构体的自引用 结构体内存对齐 结构体传参
半生瓜的blog
2023/05/12
4250
C语言学习——结构体_联合体_枚举用法直通[通俗易懂]
所谓结构体数组,是指数组中的每个元素都是一个结构体。在实际应用中,C语言结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生、一个车间的职工等。
全栈程序员站长
2022/09/23
5880
C语言学习——结构体_联合体_枚举用法直通[通俗易懂]
OC基础--数据类型与表达式
做iOS开发有3年了,从当初的小白到现在,断断续续看过很多资料,之前也写过一些博文来记录,但是感觉知识点都比较凌乱。所以最近准备抽时间把iOS开发的相关知识进行一个梳理,主要分为OC基础、UI控件、多线程、动画、网络、数据持久化、自动布局、第三方框架等几个模块进行梳理。本系列的所有博文集合参见:iOS开发知识梳理博文集。本文主要介绍 OC基础--数据类型与表达式。
mukekeheart
2020/09/07
1.1K0
【自定义类型:结构体,枚举,联合】
既然答案不是6,而是12,那么12又是如何得来的呢? 通过上面的结构体,我们发现创建的顺序分别是c1->i->c2,那么内存的开辟也是按照这个顺序进行开辟的,char->int->char。在char已经开辟了一个字节之后,int如果接着下一个字节进行开辟,那么结果一定是6,故int一定不是接着char的下一个字节进行开辟的,通过反推我们发现:int在第五个字节开辟,即前四个字节中的第二三四个字节没有被使用,故我们知道了一个这样的规则:第一个成员变量在与结构体变量为0的地址处开辟,即char占用了0到1之间的字节。之后的成员变量要对齐到该成员变量占有字节大小的整数倍的位置上:
每天都要进步呀
2023/03/28
4950
【自定义类型:结构体,枚举,联合】
【C语言】自定义类型:结构体,枚举,联合以及内存对齐的原理和原因
首先,结构体关键字是struct,例如定义一个学生类型:struct Stu;Stu是结构体标签 ,struct Stu 整体就是结构体类型;
YoungMLet
2024/03/01
2230
【C语言】自定义类型:结构体,枚举,联合以及内存对齐的原理和原因
江哥带你玩转C语言 | 14 - 结构体-枚举-共用体
struct Student { int age; struct Student stu; };
极客江南
2021/07/11
7990
c语言之共用体union、枚举、大小端模式
上一个专题我们详细的分享了c语言里面的结构体用法,读者在看这些用法的时候,可以一边看一边试验,掌握了这些基本用法就完全够用了,当然在以后的工作中,如果有遇到了更高级的用法,我们可以再来总结学习归纳。好了,开始我们今天的主题分享。
C语言与CPP编程
2020/12/02
2.2K0
c语言之共用体union、枚举、大小端模式
C语言进阶(六)--自定义类型详解(结构体+枚举+联合)
  在上述代码中,并未给结构体加上标签,所以我们在使用时无法直接使用其变量,在;前创建变量,且只能用一次。
RAIN7
2021/08/11
7070
【C语言】C语言入门知识
(1)全局变量------在{}外部定义的变量 (2)局部变量------在{}内部定义的变量
YoungMLet
2024/03/01
1.4K0
【C语言】C语言入门知识
C语言进阶-自定义类型:结构体/位段/枚举/联合
目录 前言 结构体struct 结构体的声明 结构的自引用 结构体变量的定义和初始化 空结构体大小 结构体内存对齐 修改默认对齐数 宏offsetof 结构体传参 柔性数组 struct与class的区别 位段 什么是位段 位段的内存分配 位段的跨平台问题 枚举enum 枚举类型的定义 枚举的优点 enum 与 #define 的区别 联合union 联合类型的定义 联合的特点 union和大小端 联合大小的计算 ---- 前言 ---- 本章主要讲解重点: 深入掌握结构体,枚举,联合的使用和特点,以及学会
用户9645905
2022/11/30
7300
C语言进阶-自定义类型:结构体/位段/枚举/联合
自定义类型:结构体,枚举,联合
经过了前期的一段时间的学习,函数、操作符、类型等一些列的基本单位,操作符我们能用在很多特别而又细小的地方,函数也有着其自带的强大而又众多“库函数”(官方特供的轮子),在没有对应 库函数 的时候我们也可以自定义编写所需的自定义函数,那类型呢?
比特大冒险
2023/04/16
5730
自定义类型:结构体,枚举,联合
【C语言】数组&&结构体&&枚举&联合详解
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统
用户10925563
2024/06/04
2160
【C语言】数组&&结构体&&枚举&联合详解
自定义类型:结构体,枚举,联合
我们已经掌握了结构体的基本使用了。 现在我们深入讨论一个问题:计算结构体的大小。 这也是一个特别热门的考点: 结构体内存对齐
绝活蛋炒饭
2024/12/16
1220
自定义类型:结构体,枚举,联合
C结构、联合、枚举
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
WuShF
2023/03/06
5980
C结构、联合、枚举
C语言从入门到实战——联合体和枚举
C语言中,联合体(union)是一种特殊的数据类型,允许存储不同类型的数据在同一块内存空间中。联合体的大小取决于其中最大的成员的大小,共享同一块内存空间的成员可以存储不同类型的数据。
鲜于言悠
2024/03/20
2550
C语言从入门到实战——联合体和枚举
【C语言】自学终极笔记
函数包括:函数首部(第一行)+函数体(‘{’+内容+‘}‘),函数体=函数声明(即函数原型)+执行部分。
SarPro
2024/02/20
1850
【C语言】自学终极笔记
[C语言]结构体进阶与枚举联合
有时候我们需要将不同类型的数据组合成一个有机的整体,如:一个学生有学号、姓名、性别、年龄、地址等属性.显然单独定义以上变量比较繁琐,数据不便于管理,C语言中给出了另一种构造数据类型——结构体.
IT编程爱好者
2023/04/12
6500
[C语言]结构体进阶与枚举联合
C语言自定义类型
风中的云彩
2024/11/07
1120
C语言自定义类型
推荐阅读
相关推荐
详解自定义类型:结构体,位段,枚举,联合
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验