C语言枚举、构造类型内存计算

C语言枚举、构造类型内存计算


前言

以下共阐述枚举、共用体、结构体,共用体或联合体嵌套下内存大小的计算。


一、枚举

枚举是一个基本类型,一般多用于了做信息的标志和信息的分类,是一个整数常数的集合,内存大小的计算

代码如下(示例):

#include <stdio.h>
enum test{
    state1,
    state2,
    state3,
    state4,
};

void main()
{
    enum test user_enum;
    printf("%ld",sizeof(enum test));
    printf("%ld",sizeof(state1));
    printf("%ld\r\n",sizeof(user_enum));
}

运行结果:
444

二、结构体

验证空间分配的规则

1.按照结构体中最大类型大小作为每次分配内存大小,每当放不下至少再分配最大类型大小的内存
2.按照该机器char 1字节 int或float 4字节 long 或double 8字节 ,分配的地址开头需要可以整除放入类型占用大小 。(每个成员分配的首地址均可整除放入类型的大小)。
举个例子解释上述内存计算规则:

 struct user_test{
 char a;
 double num;
 char b;
 float d;
}test;

1.首先找到内部占用内存最大的类型,即为double 8字节决定每次分配空间大小(第一条准则)
2.首先给char a分配 一个字节的空间,那么按照64位机器地址空间为8字节,那么剩余的7个字节空间不够容纳后面的double了(或者说地址不可整除8了需要向下找到一个可整除8的)。
3.于是在新的8字节连续空间上放置double 变量 将8个字节占满。
4.在第三个8字节空间上拿一个字节放char b剩下的7字节用于放float 此时要用到(第三条准则),假设char b的地址为391753777(十进制),那么他后面的的七个地址将会是391753778、391753779、391753780等 我们可以使用计算器计算下391753778、391753779、二位都不可以整除(float 4)
只有391753780可以且后面依然够4个空间(64位机器)因此可以盛放float。
因此此例总共需要分配24字节空间。


eg1:

struct user_test{
  char a;
  char b;
}test;

sizeof(test)=2字节
按照规则:首先每次只会以char(1字节)开辟空间 因此两个char开辟连续两个字节即可(整除1)。

在这里插入图片描述

eg2:

struct user_test{
  char a;
  short num;
}test;

sizeof(test)=4;
按照规则将会按照short(双字节)进行分配,首先为char a分配1个字节的空间(首地址保证要可整除1(char 类型)),之后再分配两个字节用于放置short,因为93016083无法整除2因此向下偏移 找到了93016084可以整除2,从该地址放short b

在这里插入图片描述

eg3:

struct user_test{
  int a;
  char b;
}test;

sizeof(test)=8;
按照分配规则首先找出最大的类型即int (4字节)因此首先分配4个字节用于放置int a 之后开辟4个字节用于放置char 剩余3字节为空。

在这里插入图片描述

eg4:

struct user_test{
 char a;
 double b;
 int c;
 long d;
 char e[2];
 short f;
 float g;
}test;

sizeof(test)=40
按照最大的类型开辟空间为long类型或者double类型(8字节)首先开辟8字节放置char a由于放置char a后(264736833–264736839之间不可整除8)因此需要重开一行放置double,之后放置int
类型按照地址可整除4放置,由于264736852—2647368555区间不可整除8,因此需要重新开一行放置long,之后以此类推,最后总共40字节。

在这里插入图片描述

下面提供类一个参考代码方便读者编写环境测试:

代码如下(示例):

#include <stdio.h>

struct user_test{
  int a;
  char num[5];
  short b;
  int c;
}test;

void main()
{
    printf("%ld\r\n",sizeof(struct user_test));
    printf("%ld\r\n",sizeof(test.a));
    printf("%ld\r\n",sizeof(test.b));
    printf("%d\r\n",&test.a);
    printf("%d\r\n",&test.num[0]);
    printf("%d\r\n",&test.num[5]);
    printf("%d\r\n",&test.b);
    printf("%d\r\n",&test.c);
}

运行结果:
16
4
2
1939472416
1939472420
1939472425
1939472426
1939472428

三.共用体

1.共用体各个成员的首地址相同。
2.占用内存以共用体中最大的变量类型作为开辟大小。
代码如下(示例):

union user{
    char a;
    double b;
    int c;
}test;

sizeof(union user)=8;
解析:以最大类型进行开辟空间 该例中最大为double类型因此为8字节
该处使用的url网络请求的数据。

union user{
    		char a;
    		struct{
	   				char b;
	   				double c;
       				int d;
				   }demo;
    		int e;
}test;

sizeof(union user)=24;
解析:因为该公用体中嵌套结构体,因此以结构体类型大小作为共用体类型内存大小,其中该共用体中的结构体占用24字节因此该共用体大小为24


三.嵌套类型

struct exper {
   int a1;
   union user{
              	char a;
              	struct {
                           char b;
                           double c;
                           int d;
                     	}demo;
              	int e;
              }test;
   float b1;
}info;

sizeof(struct exper)=40
分析:本例子将前面共用体处的例子包含进来 ,用结构体嵌套共用体,共用体又嵌套结构体,
这样的例子还是要找出最大数据类型,因为构造类型也是数据类型,因此其中union占用24字节,因此首地址1135865920可以整除4(int类型),之后需要找一个可以整除24的地址放共用体,1135865928可以整除24 由此开辟24字节,之后1135965952可以整除4放置float。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值