前言
以下共阐述枚举、共用体、结构体,共用体或联合体嵌套下内存大小的计算。
一、枚举
枚举是一个基本类型,一般多用于了做信息的标志和信息的分类,是一个整数常数的集合,内存大小的计算
代码如下(示例):
#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。