构造类型
数据类型分类
结构体
结构体的定义
-
定义:自定义数据类型的一种,关键字 struct ,结构体类型的变量可以存储多个不同数据类型的数据。
-
定义格式:
struct 结构体名
{
数据类型1 成员名称1;
数据类型2 成员名称2;
…
}
注意:结构体中定义的变量,我们称之为成员变量。
-
格式说明:
- 结构体名:合法的标识符,建议单词的首字母大写
- 数据类型n:C语言支持的所有类型
- 成员名称:合法的标识符,就是变量的命名标准
- 数据类型n 成员名称n:类似于定义变量,定义了结构体中的成员
-
注意:
-
结构体在定义的时候,成员不能赋值
-
举例:
struct Cat {int age = 5;// 错误,结构体定义的时候,成员不能赋值double height; // 正确 }
-
-
常见的定义格式:
-
方式1:常规定义(命名结构体,只定义类型)—推荐
struct Student {int num;// 学号char name[20];// 姓名char sex;// 性别int age;// 年龄char address[100];// 家庭住址 }
-
方式2:定义匿名结构体(常用于作为其他结构体的成员使用)
struct Dog {char *name;// 姓名int age;// 年龄struct // 此时这个结构体就是匿名{int year;// 年int month;// 月int day;// 日} birthday; }
注意:定义匿名结构体的同时必须定义结构体变量,否则编译报错,结构体可以作为另一个结构体的成员。
-
总结:
-
结构体可以定义在局部位置,也可以定义在全局位置;
-
全局位置的结构体名和局部位置的结构体名可以相同,就近原则(和普通变量的定义同理)
-
结构体类型的使用:
利用结构体类型定义变量,定义数组;结构体类型的使用与基本数据类型的使用类似。
结构体变量的定义
-
三种形式定义结构体变量:
结构体变量也称为结构体的实力。
-
第一种
① 先定义结构体
② 然后使用 struct 结构体名 变量名 ;
// 先定义结构体(先定义结构体这个数据类型) struct A {int a;char b; } // 定义结构体变量 struct A x; struct A y;
-
第二种
在定义结构体的同时,定义结构体变量;
// 定义结构体的同时定义结构变量 struct A {int a;char b; } x,y; struct A z;
此时定义了一个结构体A,x和y是这个结构体类型的变量。
-
第三种:不推荐
在定义匿名结构体的同时,定义结构体变量;
struct {int a;char b; } x,y;struct {int a;char b; } z;
此时定义了一个没有名字的结构体(称为匿名结构体);y,x是这个匿名结构体类型的变量;
-
-
匿名结构体:—弊大于利(尽量少用)
-
优点:少写一个结构体名称
-
缺点:只能使用一次;定义的结构体类型的同时就必须定义变量
-
应用场景:
-
当结构体的类型只需要使用一次,并且定义类型的同时定义变量。
-
作为其他结构体的成员使用。
-
-
-
定义结构体的同时,定义结构体变量初始化
struct Cat {int age;char color[20]; } cat;
-
结构体成员部分初始化是,大括号不能省略。
-
结构体的成员,没有默认值,是不确定的数
案例:
/** * 结构体变量的定义 */ #include <stdio.h> // 先定义结构体,再定义结构体变量 void fun1() {// 先定义结构体struct A{int a;char b;};// 再定义结构体变量struct A x;struct A y; } // 定义结构体的同时定义结构体变量 void fun2() {struct A{int a;char b;} x,y;struct A z; }// 定义匿名结构体的同时定义结构体变量 void fun3() {struct{int a;char b;} x,y;struct{int a;char b;} z; } int main() {fun1();fun2();fun3();return 0; }
-
结构体变量的使用
-
结构体变量访问结构体成员
-
格式
结构体变量名.成员名;
可以通过访问给成员赋值(存数据)
可以通过访问获取成员的值(取数据)
-
结构体变量未初始化,结构体的成员值随机(不确定)
-
-
结构体变量在定义时,可以初始化
-
建议用大括号标明数据的范围
-
结构体成员初始化时,可以部分初始化,部分初始化时一定要带大括号标明数据的范围
-
-
案例:
/** * 结构体变量的初始化 */ #include <stdio.h> /* 全局的结构体(数据类型) */ struct Dog {char *name;// 姓名int age;// 年龄char sex;// M:公,W:母 }; /* 先定义,再初始化 */ void fun1() {// 定义一个结构体// struct Dog// {// char *name;// 姓名// int age;// 年龄// char sex;// M:公,W:母// };// 定义结构体变量struct Dog dog;// 给结构体变量的成员赋值dog.name = "旺财";dog.age = 5;// 访问结构体变量的成员printf("%s,%d,%c\n",dog.name,dog.age,dog.sex); } /* 定义的同时初始化 */ void fun2() {// 定义结构体变量并初始化struct Dog dog = {"招财",23,'M'};// 修改成员的值dog.name = "进宝";// 访问结构体变量的成员printf("%s,%d,%c\n",dog.name,dog.age,dog.sex); } int main() {fun1();fun2();return 0; }
结构体数组的定义
-
什么时候需要结构体数组?
-
比如:我们需要管理一个学生对象,只需要定义一个 struct Student majie;
-
假如:我们需要管理多个学生对象,此时就需要一个结构体的数组 struct Student students[64]; 。
-
-
三种形式定义结构体数组
-
第一种:先定义结构体类型,然后定义结构体变量,再将变量存储到结构体数组中
// 定义一个学生类型的结构体 struct Student {char *name;int age;float scores[3];// 三门课程的成绩 };// 定义结构体对象 struct Student zhangsan = {"张三",23,{67.5,89.0,90.0}}; struct Student lisi = {"李四",21,{77.0,80.0,85.0}};// 定义结构化数组 struct Student students[3] = {zhangsan,lisi};
-
第二种:定义结构体类型,然后定义结构体数组并初始化
// 定义一个学生类型的结构体 struct Student {int id;char *name;int age;float scores[3];// 三门课程的成绩 }; // 定义结构体数组并初始化 struct Student students[3] = {{1,"张三",23,{67.5,89.0,90.0}},// 注意:这里赋值的顺序需要跟成员在结构体中的顺序一致{2,"李四",21,{77.0,80.0,85.0}} };
-
第三种:定义结构体类型同时定义结构体数组并初始化
// 定义一个学生类型的结构体 struct Student {int id;char *name;int age;float scores[3];// 三门课程的成绩 } ;students[3] = {{1,"张三",23,{67.5,89.0,90.0}},// 注意:这里赋值的顺序需要跟成员在结构体中的顺序一致{2,"李四",21,{77.0,80.0,85.0}} };
-
第四种:定义结构体类型同时定义结构体数组,然后通过索引给结构体成员赋值
// 定义一个学生类型的结构体 struct Student {int id;char *name;int age;float scores[3];// 三门课程的成绩 } sts[3];sts[0].id = 1; sts[0].name = "张三"; sts[0].age = 12; sts[0].scores[0] = 98;
小贴士:
结构体数组名访问结构体成员:
-
,21,{77.0,80.0,85.0}}
};
```
-
第四种:定义结构体类型同时定义结构体数组,然后通过索引给结构体成员赋值
// 定义一个学生类型的结构体 struct Student {int id;char *name;int age;float scores[3];// 三门课程的成绩 } sts[3];sts[0].id = 1; sts[0].name = "张三"; sts[0].age = 12; sts[0].scores[0] = 98;
小贴士:
结构体数组名访问结构体成员:
格式:结构体数组名 -> 成员名