sizeof计算结构体、枚举、联合体所占空间

本文深入解析C语言中sizeof运算符的使用,详细说明结构体、联合体和枚举类型的内存分配规则,帮助读者理解不同数据类型在内存中的存储方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载于:https://blog.youkuaiyun.com/programmer_at/article/details/49423891作者:猪杂汤饭

                https://zhidao.baidu.com/question/183477298                           作者:zrrhx 

                https://blog.youkuaiyun.com/yansj_scu/article/details/45310715          作者: yansj_scu

              感谢大佬的详细的撰写!

#include <stdio.h>
int main()
{
    //测试结构体大小
    typedef struct Student
    {
        int id;
        char name[10];
        int score;
    }stu;
    printf("结构体Student的大小为%d\n", sizeof(Student));

 
//联合体
union foo{
	char s[10];    //对齐单位:1,总长度:10
	int a;         //对齐单位:4,总长度:4
}Foo1; 
	 printf("联合体的大小为%d\n", sizeof(Foo1));
     
enum Day{
    saturday,
    sunday = 0,
    monday,
    tuesday,
    wednesday,
    thursday,
    friday
} workday; //变量workday的类型为枚举型enum DAY
   
printf("enum的大小为%d\n", sizeof(workday));
    return 0;
}

 

 

一、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=10

struct 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)的整数倍:52

typedef 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
BBBB
CCC

                                                               内存布局

        (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个字节

ACC
BBBB

                                                   内存布局

三、联合体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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值