sizeof计算结构体、枚举、联合体所占空间
发布日期:2021-06-29 05:01:12 浏览次数:2 分类:技术文章

本文共 3075 字,大约阅读时间需要 10 分钟。

转载于:作者:

                                           作者:zrrhx 

                          作者: 

              感谢大佬的详细的撰写!

一、C语言中sizeof()是一个关键字,不是函数,不需要使用头文件,补足知识:

  1、跟int, float关键字一样,编译器自动识别他们;
  2、千万不要因为它长得像函数,就上它的当;
  3、就像getchar()的返回值是个int型而不是char型一样,C中有很多陷阱一样。

        4、基本数据类型长度

       

二、结构体struct(在没有#pragma pack宏的情况下)

声明一个空的struct 或者union,它们所占的空间都是1B.

        1、数据成员对齐规则:第一个数据成员放在offset为0的地方,之后的每个数据成员存储的起始位置要从该成员大小的整数倍开始(例如:int在32位机上为4字节,所以要从4的整数倍地址开始存储)。

struct student1{    char num[10];//对齐单位是:1}Stu1;          //总长:1*10=10struct student2{    char num[10];//[0]~[9]    int no[10];  //对齐单位是:4   [12]~[51]}Stu2;           //总长:52

         2、结构体作为成员:如果一个结构体中同时包含结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储(如struct  a中有struct b,而b中有char,int,double等元素,那么b应该从8(double类型的大小)的整数倍开始存储。

//结构体内嵌结构体struct student5{	int id;        //对齐单位是:4,[0]~[3]	double score;  //对齐单位是:8,[8]~[15]	short grade;   //[16]~[17]	Stu4 aa;       //对齐单位是:8,[24]~[47]	char name[2];  //[48]~[49]}Stu5;             //总长度应为对齐单位(8)的倍数:56

        3、结构体的总大小:即sizeof的结果。

              按之前的对齐原则计算出来的大小的基础上,必须还得是其内部最大成员的整数倍,不足的要补齐(如struct中最大为double,现在计算得到的已经是11,则总大小为16)。

struct student3{    int n0[10];  //对齐单位是:4 [0]~[39]    char num[10];//对齐单位是:1 [40]~[49]}Stu3;           //总长度应为最大对齐单位(4)的整数倍:52typedef struct student4{	int id;        //对齐单位是:4,[0]~[3]	double weight; //对齐单位是:8,[8]~[15]	float height;  //[16]~[19]}Stu4;                 //总长度应为对齐单位(8)的倍数:24

       4、注意:即使相同的成员变量,但是排的位置不一样,字节长度也不一定相等。 所以合理地安排成员变量的排序,的确可以节省空间。但是在目前硬件资源越发便宜的今天,这点内存可能就不算的上什么了。

 (1)第一种:  最大的对齐单位是4个字节,每个小格代表一个字节,以int型占用4个来作为倍数,因为A占用一个字节后,B放不下,所以开辟新的单元,然后开辟新的单元放C,所以格式一占用的字节数为:3*4=12; 

struct tagPhone{    char   A;//[0]    int    B;//[4]~[7]    short  C;//[8]~[9]}Phone;//4的整数倍12

       

A      
B B B B
C C C  

                                                               内存布局

        (2)第二种:A后面还有三个字节,足够C存放,所以C根着A后面存放,然后开辟新单元存放B数据。所以格式二占用的内存字节为2*4=8。

struct tagPhone{    char   A;//[0]    short  C;//[2]~[3]    int    B;//[4]~[7]}Phone2;     //4的整数倍:8个字节

 

A C C  
B B B B

                                                   内存布局

三、联合体union 

       1、联合体:长度为联合中元类型(如数组,取其类型的数据长度)最大的变量长度(对齐单位)的整数倍,且要大于等于其最大成员所占的存储空间

union test{     short s;//2     char  c;//1};     //那么union的在内存中占的长度是sizeof(short)=2B。
//联合体union foo{	int a;         //对齐单位:4,总长度:4	double d;      //对齐单位:8,总长度:8}Foo1;                 //对齐单位:8,最大存储长度8,因此联合体的长度应为对齐单位的倍数:8
//联合体union foo{	char s[10];    //对齐单位:1,总长度:10	int a;         //对齐单位:4,总长度:4}Foo1;                 //对齐单位:8,最大存储长度10,因此联合体的长度应为对齐单位4的倍数:12

 

//联合体union foo{	char s[10];    //对齐单位:1,总长度:10	int a;         //对齐单位:4,总长度:4	double d;      //对齐单位:8,总长度:8}Foo1;                 //对齐单位:8,最大存储长度10,因此联合体的长度应为对齐单位8的倍数:16

 

       2、联合体内嵌结构体

//联合体包含结构体typedef union foo2{	Stu4 bb;       //对齐单位:8,总长度:24	char s[10];    //对齐单位:1,总长度:10	int a;         //对齐单位:4,总长度:4	double d;      //对齐单位:8,总长度:8}Foo2;             //对齐单位:8,长度应为对齐单位的倍数:24

        3、结构体内嵌联合体

//结构体包含联合体struct student6{	char num[10];  //对齐单位:1,[0]~[9]	int no[10];    //对齐单位:4,[12]~[51]	Foo2 cc;       //对齐单位:8,[56]~[79]	char a;        //对齐单位:1,[80]	double a1;     //对齐单位:8,[88]~[95]	int a2;        //对齐单位:4,[96]~[99]}Stu6;             //对齐单位:8,长度应为对齐单位的倍数:104

  四、枚举enum

       1、enum只是定义了一个常量集合,里面没有“元素”,而枚举类型是当做int来存储的,所以枚举类型的sizeof值都为4。

enum Day{    saturday,    sunday = 0,    monday,    tuesday,    wednesday,    thursday,    friday} workday; //变量workday的类型为枚举型enum DAY

 

转载地址:https://blog.csdn.net/zhao2chen3/article/details/84795455 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:C/C++程序是如何分配内存的?
下一篇:C++笔记

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月19日 10时38分16秒