本文共 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!