前言:
若我们想要定义一个学生,我们需要得到他\她的名字、 性别、身高等等,那我们之前学的单单char类型、int类型就不够用了,为了使一个变量可以有多个类型,就有了结构体。
一.结构体的声明
1.结构体的一般声明
例如我们要描述一个学生:
struct STU
{
char name[20];//名字
char sex[5];//性别
double height;//身高
}stu;//注意:这里要打分号
struct是结构体的关键字;
STU是自定义的结构体标签名;
struct STU是结构体类型;
stu是自定义的变量名;
{}里放的是结构体成员;
注:结构体必须要以分号( ; )结尾
2.结构体的特殊声明
前面结构体的声明有自定义类型结构体标签名,若没有它确实就是一个结构体的特殊申明。
struct
{
char name[20];
char sex[5];
double height;
}stu;
struct STU
{
char name[20];
char sex[5];
double height;
}*p;
int main()
{
*p = &stu//这样的代码可以吗?
return 0;
}
编译器会把上⾯的两个声明当成完全不同的两个类型,所以是⾮法的。
匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使⽤⼀次。
二.结构体的创建和初始化
1.结构体的一般创建
struct STU
{
char name[20];//名字
char sex[5];//性别
double height;//身高
};
int main()
{
struct STU stu1 = {"张三" , "男" , 175};//初始化stu1
printf("%s %s %lf", stu1.name, stu1.sex,stu1.height);打印stu1
struct STU stu2 = {.sex = "男", .name = "李四", .height = 180};//初始化stu2
printf("%s %s %lf", stu1.name, stu1.sex,stu1.height);打印stu2
struct STU stu3[2]={{"王五","女",165},{"赵六","男",177}};//可以用数组来创建多个结构体
return 0;
}
这里有两种方法初始化结构体成员。
2.typedefy的运用
我们每次创建结构体都要写结构体类型 + 变量名,确实有更加方便的写法——用typedefy。
typedeyf struct STU
{
char name[20];//名字
char sex[5];//性别
double height;//身高
}S;
int main()
{
S s ={ 0 };//初始化结构体
return 0;
}
三.结构体的访问操作符
如果我们要修改结构体里的成员,那我们该如何访问呢?
我们这里有两种方法:
1.用 . 通过结构体变量名直接访问结构体成员。
2.用 -> 通过结构体变量名的地址来访问结构体成员。
struct STU
{
char name[20];//名字
char sex[5];//性别
double height;//身高
};
int main()
{
struct STU stu1 = { 0 };
struct STU stu2 = { 0 };
struct STU* pstu = &stu2;
//修改结构体成员
scanf("%s %s %lf", stu1.name, stu1.sex, &stu1.height);//通过 . 来访问结构体成员
scanf("%s %s %lf", pstu->name, pstu->sex, &pstu->height);//通过 -> 来访问结构体成员
//打印结果
printf("%s %s %lf", stu1.name, stu1.sex, stu1.height);
printf("%s %s %lf", pstu->name, pstu->sex, pstu->height);
return 0;
}
注意:修改和打印的时候格式字符串和参数类型要一致。
四.结构体的内存对齐
1.结构体的内存对齐规则
1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2.其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
对⻬数编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值。
3.结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。
2.结构体的内存对齐的过程
我们已经创建好了结构体,那我们创建的结构体的大小是多少?(为了方便运算改一下)
struct STU
{
char name;//名字
char sex;//性别
double height;//身高
};
int main()
{
int sz = sizeof(struct STU);//算出结构体的大小
printf("%zd",sz);//打印
return 0;
}
这里的打印结果是:
这里就是发生了结构体的内存对齐。细节过程如下:
开始时第一个成员的对齐数是1占一个字节 ,第二个成员的对齐数是1占一个字节,第三个成员的对齐数是8,所以会跳过偏移量不是8的倍数的地址,最后结构体结构体总⼤⼩为最⼤对⻬数8的倍数。