一.结构体的设计
之前我们学习了基本数据类型char,short,int,long,long long,float,double,还学习了数组类型,指针类型,但在具体的应用场景中,这些类型是不够的,有时候我们需要其中的几个一起来修饰某个变量,例如学生的信息包括char类型的姓名,char类型的性别,int类型的年龄,int类型的学号等等,因此我们需要将这些特性融合成一体,来修饰学生,由此引出了一个新的类型-----结构体类型,结构体类型是用关键字struct来定义。
1.结构体定义方法
struct Student//定义student结构体
{
char name[20];//定义char类型的姓名数组
char sex[10];//定义char类型的性别数组
int age;//定义int类型的年龄
float score;//定义float类型的成绩
long long phonenumber; //定义long long类型的电话号
}
注意:在结构体定义时,是不占用内存空间的,只有在定义结构体变量赋值时才占内存空间。
2.结构体的访问
struct Student s1={"zs","male",20,89.0,1234567890};//定义结构体变量s1并为其赋值
strcpy(s1.name,“lisi”);//更改s1的名字为lisi,使用点访问其属性
在c.文件中,定义完结构体后,需要用结构体定义变量时需要再前面加上struct,否则编译会报错,而在cpp文件中不会报错,因此我们给结构体可以重命名,这样在用结构体定义变量时就可以不用加struct了。
struct Student//定义student结构体
{
char name[20];//定义char类型的姓名数组
char sex[10];//定义char类型的性别数组
int age;//定义int类型的年龄
float score;//定义float类型的成绩
long long phonenumber; //定义long long类型的电话号
}
//以上结构体是刚刚定义的struct结构体,下来给它重定义
typedef struct Student//定义student结构体
{
char name[20];//定义char类型的姓名数组
char sex[10];//定义char类型的性别数组
int age;//定义int类型的年龄
float score;//定义float类型的成绩
long long phonenumber; //定义long long类型的电话号
}Student;//重新定义后,结构体名为Student
3.结构体的嵌套
如果想在刚刚的Student结构体中再嵌套一个家庭信息Message的结构体,可以这样做:
typedef struct Message
{
char address[20];//家庭地址
int Familynumber;//家庭电话
}Message;
typedef struct Student//定义student结构体
{
char name[20];//定义char类型的姓名数组
char sex[10];//定义char类型的性别数组
int age;//定义int类型的年龄
float score;//定义float类型的成绩
long long phonenumber; //定义long long类型的电话号
Message maeeage;//嵌套的结构体Message
}Student;
4.结构体数组
在刚才定义的Student结构体中加一个School类型的大小为5的数组
typedef struct Message
{
char address[20];//家庭地址
int Familynumber;//家庭电话
}Message;
typedef struct School
{
char schoolname[20];//学校名称
int classnumber;//班级名称
}School;
typedef struct Student//定义student结构体
{
char name[20];//定义char类型的姓名数组
char sex[10];//定义char类型的性别数组
int age;//定义int类型的年龄
float score;//定义float类型的成绩
long long phonenumber; //定义long long类型的电话号
Message maeeage;//嵌套的结构体Message
School school[5];//大小为5的school数组
}Student;
访问结构体数组的成员
Student stu={"zc","male",20,89.0,11111111,{"西安市","12345678"}};
stu.school[0]={"西安工业大学",2106};//结构体数组的赋值
strcpy(stu.mseeage.address,"咸阳市");//结构体嵌套的成员访问并改变其值
stu.school[0].classnumber=2107;//访问结构体数组的0号下标的classnumber成员并改变值
5.结构体指针
typedef struct Student//定义student结构体
{
char name[20];//定义char类型的姓名数组
char sex[10];//定义char类型的性别数组
int age;//定义int类型的年龄
float score;//定义float类型的成绩
long long phonenumber; //定义long long类型的电话号
}Student,*PStudent;//结构体指针
Student stu={"zc","male",20,89.0,1111111};
Student *q=&stu;
stu.age=21;
(*q).age=21;//指针解引用点访问属性
q->age=21;//这条和上边等价,指针用‘->’这个指向符访问属性
strcpy(q->name,"lisi");
memcpy(q->name,"lisi",5);
注意:在结构体设计时,不能包含该结构体变量,但可以包含自己的指针变量,因为前者不知道结构体的大小,后者指针的大小在特定的系统上是固定的,在x86系统上是4字节。
6.结构体大小的求法
struct A
{
char a; //1+7
long long L;//8
short s; //2+6
double d; //8
}
//sizeof(A)=32B
struct B
{
char a; //1+1
short s; //2+4
double d; //8
long long l; //8
}
//siezof(B)=24B
struct C
{
char name[10];//10
short s; //2
int a; //4
short s[2]; //4
}
siezof(C)=20B
#pragma pack(8)//默认对齐方式
struct A
{int a; //4
short s; //2+2
}
struct B
{
short b; //2+2
int c[2]; //4+4
A a; //8
char c; //1
} 21B+3B---->MIN{最大基本数据类型,8}
#pragma pack()
#pragma pack(1)
struct A
{
char c;//1
short s;//2---->前方偏移量Min{2,1}
char d;//1------>Min{1,1}
}//4B----->Min{最大基本数据类型,指定对齐方式}
#pragma pack()
#pragma pack(2)
struct A
{
int a;//4
char d;//1+1----->Min{1,2}
long long b;//8----->Min{8,2}
} // 14B----->Min{8,2}
#pragma pack()
总结:
结构体的总大小为MIN{结构体“最大基本数据类型成员所占字节数”(将嵌套结构体里的基本类型也算上,得出最大基本数据类型成员所占字节数),指定对齐方式}大小的整数倍。