一、前言
本文用来记录自己的学习过程,主要是数据结构体大小的对齐计算方式。示例为各种情况下的计算结果。
- 一、结构体成员的偏移量必须是成员大小的整数倍(0认为是任何数的整数倍)
- 二、结构体必须是所有成员大小(数组、结构体除外)的整数倍
- 三、对齐方式确实有点浪费空间,但是能够提升效率!!!
二、示例
#include <stdio.h>
#include <stdlib.h>
//一、结构体成员的偏移量必须是成员大小的整数倍(0认为是任何数的整数倍)
//二、结构体必须是所有成员大小(数组、结构体除外)的整数倍
//对齐方式确实有点浪费空间,但是能够提升效率
//1、简单结构体
struct s1{
char ch1; //1
char ch2; //1
int i; //4 2
}; //这个结构体的大小容易计算,满足两个原则即可,为8
struct s2{
char ch1; //1
int i; // 4 3
char ch2;//1
};
/*这个结构体大小是12,为什么呢?
仔细看看两个原则,要满足偏移量是成员的整数倍
ch1偏移量是0,i的偏移量不可能是1,因为1不是i大小4的倍数,所以i的偏移量是4,ch2的偏移量就变为了8
所以满足结构体大小是成员大小整数倍,就是12。*/
//2、成员包含数组的结构体
struct s3{
char ch; //1
int i; // 4 3
char str[10];//
};
/*
这个结构体的大小是20,先看前两个成员,大小是8,毋庸置疑,这个char类型的数组
只需要把它看做十个char连在一起即可,加起来就是18,再满足结构体大小为成员整数倍,所以大小就是20。*/
//3、成员包含结构体的结构体
struct s4{
char ch; //1
int i; //4 3
struct s{
char ch1;
int j;
};//未作出具体定义时,只是声明作用
float f;
};
/*里面这个结构体的大小是8,那么是否结构体大小就要向8对齐呢?这个结构体的大小是20,很明显不是8的倍数。
所以计算结构体大小时是把里面这个结构体就看做是一个char,和一个int,不是看做一个整体。*/
//4、成员包含联合体的结构体
struct s5{
char ch;
int i;
union{
char ch1;
int j;
};
};
//联合体大小就是成员中最大类型的大小,所以这个结构体大小是12.
//5、指定对齐值
//(1)对齐值小于最大类型成员值
#pragma pack(4) //指定向4对齐 最大是8
struct s6{
char ch; //1
int i; //4 3
float f; //4
double d;//8
};
//如果我们没有指定对齐值,这个结构体大小是24,我们指定向4对齐,所以大小是4的倍数,所以结构体大小是20。
//(2)对齐值大于最大类型成员值
#pragma pack(10)
struct s7{
char ch; //1
int i; //4
float f; //4
double d; //8
};
//我们指定的对齐值是10,最大为8,是否就向10对齐?不是,当指定对齐值大于自身对齐值时,向自身对其值对齐,大小是24.
int main()
{
printf("int:%d\n",sizeof(int));
printf("float:%d\n",sizeof(float));
printf("double:%d\n",sizeof(double));
printf("char:%d\n",sizeof(char));
printf("s1:%d\n",sizeof(struct s1));
printf("s2:%d\n",sizeof(struct s2));
printf("s3:%d\n",sizeof(struct s3));
printf("s4:%d\n",sizeof(struct s4));
printf("s5:%d\n",sizeof(struct s5));
printf("s6:%d\n",sizeof(struct s6));
printf("s7:%d\n",sizeof(struct s7));
system("pause");
return 0;
}