结构体,共用体,枚举相关知识
1.结构体的大小计算
在讨论这个问题之前,我们先看例子
#include<stdio.h>
typedef struct s
{
int a;
char c;
char b;
}s;
typedef struct s1
{
char c;
int a;
char b;
}s1;
typedef struct s2
{
char c;
char b;
int a;
}s2;
int main()
{
printf("%d %d %d", sizeof(s), sizeof(s1), sizeof(s2));
return 0;
}
结果:
该运行结果是否有点难理解,接下来将会慢慢讲解这些大小的由来.
1.结构体的计算大小规则
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8
- 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
2.结构体大小计算详细解释
对于构建的第一个结构体,我们按照以上规则进行分析,a的对齐数4,c和b的对齐数是1,第一个变量的偏移量为0,所以如图所示代颜色的区域,但大小是最大对齐数的整数倍,所以6不行,需要在浪费两个字节为8 4的整数倍
在画一下s1的图
这便是s1的图.
如果需要查询各个的偏移量 使用offsetof
这样操作的优点,省时间.
调节默认对齐数大小 #pragma pack()
位段
struct A
{
int a : 2;
int b : 5;
int c : 10;
int d : 30;
};
int main()
{
printf("%d ", sizeof(struct A));
return 0;
}
运行结果 :8;
该总共需要47个比特位,大于4字节,所以开辟8字节,每次开辟一个char 或 int大小的字节
位段没有不跨平台,所以要小心使用
2.枚举类型
枚举类型优点
我们可以使用 #define 定义常量,为什么非要使用枚举? 枚举的优点: 1. 增加代码的可读性和可维护性 2. 和#define定义的标识符比较枚举有类型检查,更加严谨。 3. 防止了命名污染(封装) 4. 便于调试 5. 使用方便,一次可以定义多个常量
3.共用体
#include<stdio.h>
union un
{
int a;
char c[5];
};
int main()
{
printf("%d", sizeof(union un));
return 0;
}
运行结果 8
#include<stdio.h>
union un
{
int a;
char c;
};
int main()
{
printf("%d", sizeof(union un));
return 0;
}
运行结果 4
共用体的大小是最大对齐数的整数倍,在开辟空间时,所有元素共用空间, 所以第二个是4,第一个是5,但是大小是最大对齐数的整数倍,所以为8.