一、sizeof的使用
void test1() {
char a = 23;
short b = 20;
int c = 40;
char arr[10] = { 0 };
short arr2[10] = { 0 };
int arr3[10] = { 4 };
printf("sizeof(a)=%d\nsizeof(b)%d\nsizeof(c)%d\nsizeof(arr)%d\nsizeof(arr2)=%d\nsizeof(a)=%d\n", sizeof(a), sizeof(b), sizeof(c), sizeof(arr), sizeof(arr2), sizeof(arr3));
}
struct st1
{
char a;
short b;
int c;
};
struct st2
{
char a;
int c;
short b;
};
int main(int argc, char* argv[])
{
st1 s1;
st2 s2;
test1();
printf("s1宽度=%d\n", sizeof(s1));
printf("s1宽度=%d\n", sizeof(s2));
return 0;
}
结构体变量s1和s2的成员变量一样,仅仅是顺序不同,导致的整体宽度就不一样,是为什么呢?答案在下面…
结构体对齐
先上结论:
- 数据成员对齐规则:结构的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的起始位置要从改成以大小的整数倍开始,如int在32位机为4字节,这要从4的整数倍地址开始存储;
- 结构体的总大小,即sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐;
- 如果一个结构里面有某些结构体成员,这结构体成员要从其内部最大元素大小的整数倍地址开始存储;
- 对齐参数如果比成员的sizeof小,则偏移量应该取二者的最小值;
实例分析
struct Test1{
char a; int b;//整体大小为8字节
}
struct Test2{
int a; __int64 b; char c;//整体大小为24字节
}
struct Test3{
int a; __int64 b; char c; char d;
}
数据对齐
#pragma pack(n)
结构体
#pragma pack()
其中n为字节对齐数,取值为1,2,4,8,一般默认是8
如果这个值比结构体成员的sizeof小,那么该成员的偏移量以此值为准
#pragma pack(n)
struct Test{
int a;
__int64 b;
char c;
};
#pragma pack()
n=1,2, 4, 8时:1字节对齐时–每个变量本来占多宽就存储多宽;2字节对齐时–成员宽度小于2时会补齐,大于2时,要按照每两个字节为一行的对齐,其他行不够的也要补齐;4字节和8字节同理
- 根据结构体对齐的原理,建议按照数据类型由大到小的顺序进行书写;
typedef关键字
作用:为一种数据类型定义一个新名字,这里的数据类型包括基本数据类型和自定义的数据类型(struct等)
//1、对已有类型定义别名
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
//2、一维数组类型的定义格式
typedef int vector[10];
//3、 二维数组类型的定义格式
typedef int matrix[5][5];
typedef int nameTable[5][5][5];
//4、结构体的定义格式
typedef struct student
{
int x;
int y;
}stu;
int main(int argc, char* argv[])
{
vector v;
v[0] = 1;
v[1] = 2;
v[2] = 3;
v[3] = 4;
v[4] = 5;
matrix w;
nameTable n;
w[0][0] = 1;
w[0][1] = 2;
w[0][2] = 3;
w[0][3] = 4;
w[0][4] = 5;
n[0][0][0] = 1;
char arr[10];
strcpy_s(arr, "中国");
printf("%s\n", arr);
return 0;
}
结构体数组
数组每个元素都是student类型的元素