1.结构体概念:
C语言提供了两种数据类型的聚合方式,分别是数组和结构体。数组之前已经学习过,存储的数据必须是类型相同,但这并不能满足我们使用需求,尤其是在面向对象编程的过程中,比如我们需要描述一个学生对象,这个学生包括姓名、年龄、住址、学号、成绩等信息,只用一种数据类型显然不能描述完全。因此,引入结构体这个概念,结构体可以存储不同类型的数据,这些数据称为它的成员。
2.结构体的声明
结构体声明一般放在主函数外面:
struct Student
{
char name[20];
int age;
char sex;
}student; //分号不能忘记,在这里x就是全局结构体变量
int main()
{
//其他语句;
return 0;
}
这个结构体创建了一个结构体变量student,结构体包含三个成员:名字char型数组、年龄整型age和性别字符char。在声明时可以有结构体变量student,此时结构体x是全局变量,也可以先声明结构体,在函数中再创建结构体变量,那么此时x就是局部变量。比如:
struct Student
{
char name[20];
int age;
char sex;
};
void fun()
{
struct Student XiaoMing; //这里struct Student相当于下面的int,就是一种类型标识,这里XiaoMing就是局部结构体变量
int a;
}
int main()
{
//其他语句;
return 0;
}
其中标签Student可以省略,这个结构体就成了匿名结构体,一般不建议这么做。
struct
{
int a;
char ch;
}x;
struct
{
int a;
char ch;
}a[20],*p; //a[20]包含了20个结构体,p是一个指针,它指向结果
上面两个结构都忽略了结构体标签(如Student),那么p=&x这个语句成立吗??
警告:这两个声明被编译器当做两种截然不同 的类型,即使成员相同。所以,变量a,p,x,类型不同,不可p=&x。
3.用typedef定义结构体
typedef struct
{
char name[20];
int age;
char sex;
}Student;
int main()
{
Student XiaoMing;
Student LiHUa;
return 0;
}
用typedef后,Student相当于类型名,可以用来创建变量。
4.结构体成员的访问
数组元素我们可以使用下标的方式访问,这是因为数组元素长度类型长度都相同,但结构体因为其成员类型、长度都不相同,所以不能通过下标方式来访问。但是结构体成员都有名字,可以通过名字访问他们,在这里也有两种方法。
①通过结构体变量本身,运用 . 操作符访问
struct Student
{
char name[20];
int age;
}student1;
int main()
{
strcpy(student1.name,XiaoMing);
student1.age=18;
printf("%s %d",student1.name,student1.age);
return 0;
}
②通过结构体指针,运用->进行访问
struct Student
{
char name[20];
int age;
}student1;
int main()
{
struct Student *p;
p=&student1;
strcpy(p->name,XiaoMing);
p->age=18;
printf("%s %d",p->name, p->age);
return 0;
}
两种方式的结构都为:XiaoMing 18
5.结构体自引用
结构体中可以有任意类型的数据类型,那么能不能包含其它结构体或结构体本身呢?
struct stu
{
int a;
char ch[20];
struct stu y;
}x;
这种方式的引用是不正确的,因为不知道结构体y的空间大小,系统无法为其分配空间。正确的方式如下:
struct stu
{
int a;
char ch[20];
struct stu *y;
}x;
这里的struct stu *y是指针类型,占用内存大小为4个字节。
6.结构体的定义和初始化
struct Student
{
int age;
char name[20];
double mathScore;
}xiaoMing,xiaoHong; //可直接在这里定义
struct Student s1;
struct Student s2; //也可以在这里定义
//完全初始化
struct Student xiaoMing={18,"xiaoMing",85};
//部分初始化
struct Student xiaoHong={.name="xiaoHong",.mathScore=90};
//结构体变量之间的赋值
xiaoHong=xiaoMing;
xiaoHong.name="小花" //错误的,正确应该如下
strcpy(xiaoHong.name,"小花");
//注:数组不可以整体赋值,可整体初始化。同理,结构体不可整体赋值,可以整体初始化。结构体地址数值等于第一个成员地址数值。
7.结构体内存对齐
请移步:
https://blog.csdn.net/dai_wen/article/details/78304568