0
点赞
收藏
分享

微信扫一扫

C语言 之 结构体内存对齐 - 位段 - 枚举 - 联合体

萧让听雪 2022-02-17 阅读 123

目录

一. 结构体内存对齐

1.练习题

2. 如何计算?掌握结构体对齐规则:

3.为什么存在内存对齐 ?

4.修改默认对齐数

二.位段

 1.什么是位段

 2.位段的内存分配

 3.位段的跨平台问题 

三.枚举

1.枚举的类定义

2.枚举的优点

四.联合体(共用体)

1.联合体类型定义

2.联合体大小计算 


 

 

一. 结构体内存对齐

1.练习题

//练习1
struct S1
{
 char c1;
 int i;
 char c2;
};
printf("%d\n", sizeof(struct S1)); //12

//练习2
struct S2
{
 char c1;
 char c2;
 int i;
};
printf("%d\n", sizeof(struct S2)); //8

//练习3
struct S3
{
 double d;
 char c;
 int i;
};
printf("%d\n", sizeof(struct S3)); //16

//练习4-结构体嵌套问题
struct S4
{
 char c1;
 struct S3 s3;
 double d;
};
printf("%d\n", sizeof(struct S4)); //32

2. 如何计算?掌握结构体对齐规则:

 

 

3.为什么存在内存对齐 ?

大部分的参考资料都是如是说的:

1. 平台原因 ( 移植原因 )

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。 //比如只在内存地址为4的倍数处读取

2. 性能原因

数据结构 ( 尤其是栈 ) 应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器

需要作两次内存访问;而对齐的内存访问仅需要一次访问。

总体来说:

结构体的内存对齐是拿 空间 来换取 时间 的做法

4.修改默认对齐数

之前我们见过了 #pragma 这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数

#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认


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

int main()
{
    //输出的结果是什么?
    printf("%d\n", sizeof(struct S1)); //12
    printf("%d\n", sizeof(struct S2)); //6
    return 0; 
}

结论:

结构在对齐方式不合适的时候,我么可以自己更改默认对齐数。 //最好设置为2^n,便于读取内存

 

二.位段

1.什么是位段

 

 2.位段的内存分配

 

3.位段的跨平台问题 

三.枚举

1.枚举的类定义

 

2.枚举的优点

 

四.联合体(共用体)

1.联合体类型定义

联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以 联合也叫共用体)  

2.联合体大小计算 

 

 

 

举报

相关推荐

0 条评论