一、结构体的理解
- 结构体(structure)类型是一种允许程序员把一些数据分量聚合成一个整体的数据类型。
- 结构体类型由1个以上称为域(field)的信息项组成,域也可以称为属性(attribute)或成员
二、结构体的基本语法
-
结构体的定义:
struct[结构体类型名] { 域定义表 }; 具体如下: struct 结构名{ 类型名 结构成员名1; 类型名 结构成员名2; ... 类型名 结构成员名n; };
-
结构体变量的初始化
struct 结构名 结构体变量名 ={值1,值2,值3}; 注意:{}中的各数据需要使用逗号分开,{}中的数据必须和结构体中定义的结构成员顺序、数据类型一致
-
结构成员变量的访问
结构体变量名.结构成员名 对字符串类型的成员变量的赋值:strcpy(s1.name, "杨紫");
-
案例:
#include<stdio.h> struct student{ // student为结构体类型名 char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 int grade[4]; // 成绩,最后一位可以存储总分 }; void main(){ struct student a = {"202405","张一山","男",{80,89,90}}; // 将各科分数计算总数存储在对应位置 int i,m; for(i=0,m=0;i<3;i++){ m+=a.grade[i]; } a.grade[3]=m; printf("%-8s%-11s%-5s%-5s%-5s%-5s%-5s\n","学号","姓名","性别","语文","数学","英语","总分"); printf("%-8s%-11s%-5s",a.no,a.name,a.sex); for(i=0;i<4;i++){ printf("%-5d",a.grade[i]); } }
三、结构体的其他定义方式
-
混合定义:定义结构类型的同时定义结构变量
struct 结构名{ 类型名 结构成员名1; 类型名 结构成员名2; ... 类型名 结构成员名n; }结构变量名1,结构变量名2={值1,值2,值3};
案例: #include<stdio.h> struct student{ // student为结构体类型名 char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 }s1,s2={"202405","张一山","男"}; void main(){ // 为结构体中的字符串成员赋值需要使用 strcpy strcpy(s1.no, "202406"); strcpy(s1.name, "杨紫"); strcpy(s1.sex, "女"); printf("%-8s%-11s%-5s\n","学号","姓名","性别","语文","数学","英语","总分"); printf("%-8s%-11s%-5s\n",s1.no,s1.name,s1.sex); printf("%-8s%-11s%-5s\n",s2.no,s2.name,s2.sex); }
-
无类型名定义(匿名的结构体类型)
typedef struct{ 类型名 结构成员名1; 类型名 结构成员名2; ... 类型名 结构成员名n; }结构变量名表; 注意:typedef命令定义的结构体类型使用时,不需要再写 struct
案例: #include<stdio.h> typedef struct{ // student为结构体类型名 char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 }student; void main(){ student s={"202405","张一山","男"}; printf("%-8s%-11s%-5s\n","学号","姓名","性别","语文","数学","英语","总分"); printf("%-8s%-11s%-5s\n",s.no,s.name,s.sex); }
-
结构体的嵌套定义
在定义结构成员时所用的数据类型也可以是结构类型,这种定义方式就形成了结构类型的嵌套。
#include<stdio.h> struct birthday{ int year,month,day;// 出生日期的年月日 }; struct student{ char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 struct birthday birth; }; void main(){ // 为结构体中的字符串成员赋值需要使用 strcpy struct student s1={"12345","刘亦菲","女",{1990,9,18}}; printf("%-8s%-11s%-11s%-11s\n","学号","姓名","性别","生日"); printf("%-8s%-11s%-11s%-5d-%-d-%-d\n",s1.no,s1.name,s1.sex,s1.birth.year,s1.birth.month,s1.birth.day); }
四、结构变量的使用
-
结构变量之间相互赋值
(1) 同类型的两个结构变量之间可以相互赋值 (2) 案例: #include<stdio.h> struct birthday{ int year,month,day;// 出生日期的年月日 }; struct student{ char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 struct birthday birth; }; void main(){ // 为结构体中的字符串成员赋值需要使用 strcpy struct student s2={"12345","刘亦菲","女",{1990,9,18}}; struct student s1=s2; // 同类型的结构体变量之间相互赋值 printf("%-8s%-11s%-11s%-11s\n","学号","姓名","性别","生日"); printf("%-8s%-11s%-11s%-5d-%-d-%- d\n",s1.no,s1.name,s1.sex,s1.birth.year,s1.birth.month,s1.birth.day); }
-
结构变量可以作为函数的参数进行传递
#include<stdio.h> struct birthday{ int year,month,day;// 出生日期的年月日 }; struct student{ char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 struct birthday birth; }; void main(){ // 为结构体中的字符串成员赋值需要使用 strcpy struct student s2={"12345","刘亦菲","女",{1990,9,18}}; testStudent(s2); } // 结构变量作为函数的参数 void testStudent(struct student s1){ printf("%-8s%-11s%-11s%-11s\n","学号","姓名","性别","生日"); printf("%-8s%-11s%-11s%-5d-%-d-%-d\n",s1.no,s1.name,s1.sex,s1.birth.year,s1.birth.month,s1.birth.day); }
-
结构变量可以作为函数的返回值进行返回
#include<stdio.h> struct student{ char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 }; struct student getStudent(){ struct student s={"12345","刘亦菲","女"}; return s; } void main(){ struct student s=getStudent(); printf("%-8s%-11s%-11s\n","学号","姓名","性别"); printf("%-8s%-11s%-5s\n",s.no,s.name,s.sex); }
-
结构变量可以应用在数组上:
#include<stdio.h> struct student{ // student为结构体类型名 char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 }; void main(){ // 为结构体中的字符串成员赋值需要使用 strcpy struct student stus[3]={ {"202405","张一山","男"}, {"202406","刘亦菲","女"}, {"202407","檀健次","男"} }; int i; printf("%-8s%-11s%-5s\n","学号","姓名","性别"); for(i=0;i<3;i++){ printf("%-8s%-11s%-5s\n",stus[i].no,stus[i].name,stus[i].sex); } }
五、结构指针
-
理解:结构指针就是指向结构类型变量的指针
-
语法:
(1) struct 结构体名 *结构指针名; (2) 案例:struct student *p; (3) 结构指针的值实际上存储的是结构变量的首地址
-
使用:利用结构指针访问它所指向的结构变量中的各个成员
(1) 第一种形式:用 *p 访问结构成员,(*结构指针).成员名 a. 案例: (*p).num = 100; b. 注意:(*p)中的括号是不可少的,因为成员运算符 . 的优先级高于 "*" (2) 第二种形式:用指向运算符 -> 访问指针指向的结构成员 a. 案例: p -> num = 100 b. 注意:使用结构指针访问结构成员时,通常使用指向运算符 ->
#include<stdio.h> struct student{ // student为结构体类型名 char no[7]; // 学号,最多6位数字 char name[10]; // 姓名,最多4个汉字 char sex[3]; // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 }; void main(){ struct student s={"202405","张一山","男"},*p; p=&s; printf("%-8s%-11s%-5s\n","学号","姓名","性别","语文","数学","英语","总分"); printf("%-8s%-11s%-5s\n",(*p).no,p->name,p->sex); }