结构体
一、结构体的定义与初始化
结构体是什么?
简单来说,结构体是一种自定义的复合数据类型,可由若干不同类型的成员组成,能同一表达某事物的属性。
1.如何定义
struct 结构名 // 结构名一般首字母大写
{
成员类型 成员名;
...
...
};
//eg:
struct Student
{
char name[20];
char sex;
char phone[12];
};
//我们需要自己定义结构变量、结构数组、分配堆内存才能使用。
//struct关键字不能省略
struct 结构名 结构变量名;
struct 结构名 结构数组名[n];
struct 结构名* 结构指针变量名 = malloc(sizeof(struct 结构名)*数量);
// 结构指针传参
void func([const] struct 结构名* 指针)
{
...
}
2.初始化
// 数据要与成员的顺序一一对应。
struct 结构名 结构变量名 = {v1,v2,v3,...};
struct 结构名 结构数组[n] = {
{v1,v2,v3,...},
{v1,v2,v3,...},
...
};
// 指定成员初始化
struct 结构名 结构变量名 = {
.成员名1 = 初始化数据1,
.成员名2 = 初始化数据2,
...
};
struct 结构名 结构数组[n] = {
{.成员名1 = 初始化数据1,.成员名2 = 初始化数据2,...},
{.成员名1 = 初始化数据1,.成员名2 = 初始化数据2,...},
{.成员名1 = 初始化数据1,.成员名2 = 初始化数据2,...},
...
};
3.如何访问
//eg:
struct Student
{
char name[20];
char sex[3];
char phone[12];
};
struct Student stu = {
.name = "张三",
.sex="男",
.phone = "13109876543"
};
<1>
printf("%s %s %s\n",stu.name,stu.sex,stu.phone);
<2>
void show_student(const struct CStudent* stu)
{
printf("%s %s %s\n",stu->name,stu->sex,stu->phone);
}
show_student(&stu);
3.使用typedef重定义简化使用过程
typedef struct Student{
.name = "张三",
.sex="男",
.phone = "13109876543"
}Student;
//定义等过程与上述类似,只是将struct Student简化为Student
二、结构体的总字节数
1.内存对齐
假定从0字节排列结构的第一个成员,之后所有成员的起始字节数,必须是成员本身字节数的整数倍,如果不是则填充一些空闲字节。
typedef struct Data
{
char ch; // 0
// 1 2 3 空闲了3个字节用于内存对齐
int num; // 4 5 6 7
}Data;
[][][][]
int main(int argc,const char* argv[])
{
Data d;
printf("%p %p\n",&d.ch,&d.num);
// 000000000061FE18 000000000061FE1C
printf("%d\n",sizeof(d)); //8
}
2.内存补齐
结构的总字节数必须是它最大成员字节数的整数倍,如果不是则在结构的末尾填充一些空闲字节。
typedef struct Data
{
char ch; // 0
// 1 2 3
int num; // 4 5 6 7
short sh; // 8 9
// 10 11
}Data
int main(int argc,const char* argv[])
{
Data d;
printf("%p %p\n",&d,&d.sh);
//000000000061FE14 000000000061FE1C
printf("%d\n",sizeof(d));//12
}
3.不同系统下对齐补齐的差异
①32位
// 在Linux32位系统下,超过4字节按4字节计算。
typedef struct Data
{
char ch; // 0
// 1 2 3
double num; // 4 ~ 11 按4字节对齐
short sh; // 12 13
// 14 15 按4字节补齐
}Data;
int main(int argc,const char* argv[])
{
printf("%d\n",sizeof(Data)); // 16
}
// 在Windows32位系统下,超过8字节按4字节计算
typedef struct Data
{
char ch; // 0
// 1 2 3
long double num; // 4 ~ 15 按4字节对齐
short sh; // 16 17
// 18 19 按4字节补齐
}Data;
int main(int argc,const char* argv[])
{
printf("%d\n",sizeof(Data)); // 20
}
#include <stdio.h>
// 在Windows32位系统下,未超过8字节,按成员的实际字节对齐补齐
typedef struct Data
{
char ch; // 0
// 1 2 3 4 5 6 7
double num; // 8 ~ 15
short sh; // 16 17
// 18 19 20 21 22 23
}Data;
int main(int argc,const char* argv[])
{
printf("%d\n",sizeof(Data)); // 24
}
②64位
// Windows64位系统和Linux64位系统,都按成员的字节数计算内存对齐、内存补齐
typedef struct Data
{
char ch; // 0
// 1 2 3 4 5 6 7 8 9 11 12 13 14 15
long double num; // 16 ~ 31
short sh; // 32 33
// 34 35 36 37 38 39 40 41 42 42 44 45 46 47
}Data;
int main(int argc,const char* argv[])
{
printf("%d\n",sizeof(Data));//48
}
③不同系统下long类型字节数
Linux32位系统 4字节
Linux64位系统 8字节
Windows32位系统 4字节
Windows64位系统 4字节