09 字节对齐_结构体数组
- 一、sizeof关键字
- 1.1 基本类型的sizeof
- 1.2 数组类型的sizeof
- 1.3 结构体类型的sizeof
- 二、字节对齐--结构体对齐
- 2.1 结构体对齐
- 2.2 对齐规则
- 2.2.1对其参数规则
- 2.2.2 数据成员对齐规则
- 2.2.2.3 结构体的总大小
- 2.2.2.4 结构体嵌套
- 三、typedef关键字
- 3.1 对已有类型定义别名
- 3.2 一维数组类型的定义格式
- 3.3 二维数组类型的定义格式
- 3.4 结构体的定义格式
- 四、作业
一、sizeof关键字
1.1 基本类型的sizeof
可以适用类型,也可以适用变量
1.2 数组类型的sizeof
1.3 结构体类型的sizeof
二、字节对齐–结构体对齐
2.1 结构体对齐
- 例1
struct Test
{char a;int b ;
};
int main(int argc, char* argv[]){Test t;printf("%d\n",sizeof(t));printf("%d\n",sizeof(Test));return 0;
}
- 例2
struct Test
{int a ;__int64 b ;char c ;
};int main(int argc, char* argv[]){Test t;printf("%d\n",sizeof(t));printf("%d\n",sizeof(Test));return 0;
}
8的倍数
- 例3
struct Test
{int a ;__int64 b ;char c ;char d ;
};
int main(int argc, char* argv[]){Test t;printf("%d\n",sizeof(t));printf("%d\n",sizeof(Test));return 0;
}
2.2 对齐规则
2.2.1对其参数规则
#pragma pack( n )
struct AA{//…...
}
#pragma pack( )
1.对齐参数:n为字节对齐数,其取值为1、2、4、8,默认是8。
2.如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值.
对其操作为:
2.2.2 数据成员对齐规则
结构的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储).
2.2.2.3 结构体的总大小
结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
2.2.2.4 结构体嵌套
如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。如(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储.)
三、typedef关键字
typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。
3.1 对已有类型定义别名
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
3.2 一维数组类型的定义格式
typedef int vector[10];
int main(int argc, char* argv[])
{vector v;v[0] = 1;v[1] = 2;v[2] = 3;v[3] = 4;v[4] = 5;return 0;
}
3.3 二维数组类型的定义格式
typedef int name[5][5];
typedef int nameTable[5][5][5];
int main(int argc, char* argv[])
{matrix v;nameTable n;v[0][0] = 1;v[0][1] = 2;v[0][2] = 3;v[0][3] = 4;v[0][4] = 5;n[0][0][0] = 1;return 0;
}
3.4 结构体的定义格式
typedef struct student
{int x;int y;
}stu;
四、作业
- 代码
#include <stdio.h>
#include <string.h>struct Point{float x;float y;float z;
};struct Monster{char name[30];int level;int ID;int damage;int blood;Point point;
};
Monster monster[10];void Assignment(){strcpy(monster[0].name, "这是一个精英怪");monster[0].level = 20;monster[0].ID = 1001;monster[0].damage = 18;monster[0].blood = 360;monster[0].point.x = 20.1;monster[0].point.y = 20.1;monster[0].point.z = 20.1;
}void Print(){printf("怪物的名字是:%s\n", monster[0].name);printf("怪物的等级是:%d\n", monster[0].level);printf("怪物的ID是:%d\n", monster[0].ID);printf("怪物的伤害是:%d\n", monster[0].damage);printf("怪物的血量是:%d\n", monster[0].blood);printf("怪物的位置x坐标是:%f\n", monster[0].point.x);printf("怪物的位置y坐标是:%f\n", monster[0].point.y);printf("怪物的位置z坐标是:%f\n", monster[0].point.z);
}
int main(int argc, char* argv[]){Assignment();Print();return 0;
}
- 顺便画个字节对齐分析图
共计一个Monster结构体大小为60字节。
printf(“%d\n”, sizeof( monster[0]));得到60
printf(“%d\n”, sizeof(Monster));得到60
- 顺便反汇编看看