C语言面试宝典之计算结构体的大小

C语言面试宝典之计算结构体的大小,第1张

1.结构体的大小并不是简单的成员大小的相加,而是有两个规则要符合的。



规则一:结构体成员的偏移量必须是该成员的大小的整数倍(0被认为是任何数的整数倍)
穿插一点补充:记住偏移量是指当前成员前面成员所占的字节数,例如下面Test1那里,int前面已 经有char了,按道理说其偏移量是1的,但为了对齐,必须在加多3形成4与int对齐,所以1+3 = 4,int的偏移量为4,最后一个char的偏移量为4+4为8,8+1为9,那么9是不是这个结构体的大小呢,显然不是,其实是12,继续看原则二。


规则二:结构体大小必须是结构体成员大小的整数倍(数组,结构体除外)
对齐方式虽然浪费了内存空间,但是对齐方式提高了计算机对程序的访问效率
任何一个结构体的大小都要符合上述两个原则。


struct Test1{
    char i; //1
    int  ch; //4  +3
    char k;  //1
};

2.接下来我们分类看一下结构体的大小的计算方式
(1)简单类

struct Test1
{
	char ch; //1
	int i;   //4 +3
	char chr;//1
};//这时结构体的大小为12
由于最后一个char的偏移量是8,但8+1 = 9并不是int大小的整数倍,
所以要继续往后移,到12时就合适了是所有成员大小的整数倍了,所以其大小为12

(2)简单类2

struct Test2
{
	char che; //1
	char cha; //1
 	int  i;   //4  +2
};//这时候结构体大小为8
由于int前面的偏移量为2,但2并不是int大小的整数倍,所以要加2偏移量变为4,所以4+4 = 8,
8即是1的倍数,也是4的倍数,所以这个结构体大小为8

(3)结构体含数组1

struct Test3
{ /*这时候这个结构体的大小是136,因为数组不要求偏移量是
    其大小整数倍,数组大小直接加上前面的成员大小即可*/
	int studentId;   //4
	char name[128];  //128
	int scores;      //4
};
这时候这个结构体的大小是136,因为数组不要求偏移量是其大小整数倍,
数组大小直接加上前面的成员大小即可,由于132是最后int的倍数,所以其大小为132+4 = 136
切记,结构体的大小不需要是数组大小的整数倍

(4)结构体数组2

struct Test4
{结构体的大小不要求是数组的整数倍,只要是其他成员大小的整数倍即可
	char id;  //1
  	int num;  //4  +3
 	char name[10]; //10
}; 大小为20,如果是18的话,其不是int的整数倍,所以要偏移到20才行

(5)结构体里嵌套结构体

struct Test5
{
	char ch; //1
	int  i;  //4
    struct s //16
	{
        char ae;//1
        int j;  //4
        double h;//8		
	}temp;
	
	float f; //4
};//这时结构体大小为32
其实这是按照不同编译器,其大小不一样的,
但嵌套在里面的结构体当它不存在即可,嵌套结构体里的成员按照顺序参与计算即可

(6)结构体里有联合体

struct Test6
{
	char ch; //1
	int i; //4
	union//我们知道联合体的大小就是里面最大成员的大小,这时候联合体的大小是4
	{
		char cj; //1
		int g; //4
	};
};//这时大小为12
联合体大小计算是遵循联合体里最大的成员是多少,其联合体大小就是多少
所以8+4 = 12,这结构体大小为12

(7)指定与什么对齐1

#pragma pack(4) 这里是指定跟什么对齐的意思
切记,与什么对齐,偏移量就是什么的整数倍
struct Test7
{
	char ch; //1
	int j;   //4
	float a; //4
	double d;//8
};这里如果有指定与4对齐的话,大小是20,如果没指定的话就是24
指定与什么对齐,即其偏移量跟结构体大小都要是其指定对齐数的整数倍即可

(8)指定与什么对齐2

#pragma pack(16)
/*这里有个小插曲,如果指定对齐的数比结构体里最大的成员大小小的话,就按照对齐数来对齐
相反,如果指定的对齐数比结构体里最大成员还大的话,那么就按照结构体里的对齐方式来。


*/ struct Test8 { char ch; //1 int j; //4 float h; //4 double g;//8 };//这时候的大小为24 这里有个小插曲,如果指定对齐的数比结构体里最大的成员大小小的话,就按照对齐数来对齐 相反,如果指定的对齐数比结构体里最大成员还大的话,那么就按照结构体里的对齐方式来。


完整代码:

#include 

//计算结构体大小要遵循两个原则
//结构体成员的偏移量必须是该成员的大小的整数倍(0被认为是任何数的整数倍)
/*记住偏移量是指当前成员前面的空间数,例如下面的char name前面已经有int,
  因为int是占四个字节的,所以其偏移量是4*/
//结构体大小必须是(数组,结构体除外)结构体成员大小的整数倍。


//对齐的方式虽然浪费了空间,但是对齐方式提高了计算机对程序的访问效率 //任何一个结构体都要符合上面两条规则 struct Test1 { char ch; //1 int i; //4 +3 char chr;//1 };//这时结构体的大小为12 struct Test2 { char che; //1 char cha; //1 int i; //4 +2 };//这时候结构体大小为8 struct Test3 { /*这时候这个结构体的大小是136,因为数组不要求偏移量是 其大小整数倍,数组大小直接加上前面的成员大小即可*/ int studentId; //4 char name[128]; //128 int scores; //4 }; struct Test4 {//结构体的大小不要求是数组的整数倍,只要是其他成员大小的整数倍即可 char id; //1 int num; //4 +3 char name[10]; //10 }; //大小为20,如果是18的话,其不是int的整数倍,所以要偏移到20才行 struct Test5 { char ch; //1 int i; //4 struct s //16 { char ae;//1 int j; //4 double h;//8 }temp; float f; //4 };//这时结构体大小为32 struct Test6 { char ch; //1 int i; //4 union//我们知道联合体的大小就是里面最大成员的大小 { char cj; //1 int g; //4 }; };//这时大小为12 #pragma pack(4) //这里是指定跟什么对齐的意思 //切记,与什么对齐,偏移量就是什么的整数倍 struct Test7 { char ch; //1 int j; //4 float a; //4 double d;//8 };//这里如果有指定与4对齐的话,大小是20,如果没指定的话就是24 #pragma pack(16) /*这里有个小插曲,如果指定对齐的数比结构体里最大的成员大小小的话,就按照对齐数来对齐 相反,如果指定的对齐数比结构体里最大成员还大的话,那么就按照结构体里的对齐方式来。


*/ struct Test8 { char ch; //1 int j; //4 float h; //4 double g;//8 };//这时候的大小为24 //ctrl s+d是复制当行内容到下一行 int main() { //计算结构体的大小的方式 printf("the size of int:%d\n",sizeof(int)); printf("the size of char:%d\n",sizeof(char)); printf("the size of float:%d\n",sizeof(float)); printf("the size of double:%d\n",sizeof(double)); printf("\n"); printf("the size of Test1 :%d\n",sizeof(struct Test1)); printf("the size of Test2 :%d\n",sizeof(struct Test2)); printf("the size of Test3 :%d\n",sizeof(struct Test3)); printf("the size of Test4 :%d\n",sizeof(struct Test4)); printf("the size of Test5 :%d\n",sizeof(struct Test5)); printf("the size of Test6 :%d\n",sizeof(struct Test6)); printf("the size of Test7 :%d\n",sizeof(struct Test7)); printf("the size of Test8 :%d\n",sizeof(struct Test8)); return 0; }

结果:

the size of int:4
the size of char:1
the size of float:4
the size of double:8

the size of Test1 :12
the size of Test2 :8
the size of Test3 :136
the size of Test4 :20
the size of Test5 :32
the size of Test6 :12
the size of Test7 :20
the size of Test8 :24

以上内容很重要,耐心观看。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/621772.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-15
下一篇 2022-04-15

发表评论

登录后才能评论

评论列表(0条)

保存