第14讲 结构体和共用体 计算机与通信工程学院
第14讲 结构体 本讲主要内容 一、结构体 1. 结构体类型 2. 结构体变量 3. 结构体数组 4. 结构体指针 二、共用体
一、结构体类型 结构体类型概述 表13-1 学生信息表 学 号 姓 名 性别 年龄 成绩 地 址 学 号 姓 名 性别 年龄 成绩 地 址 990101 Liujia M 19 87.5 shanghai 990102 Wangkai 18 89.5 Beijing 990103 Xiaohua F 20 81.0 Qingdao 990104 Zhangli 82.0 Guangzhou 990105 wangfeng 88.5 nanchang 表中的每一行反映了一个学生的综合信息,是一个学生的整体数据。每一个数据,都由多个数据项组成,包括学生的学号、姓名、性别、年龄、成绩、地址等,各数据项的数据类型也不尽相同。要表示这样一个组合数据,仅靠单一的任何一种数据类型,如整型、实型、数组等,都是不能实现的。
一、结构体类型 “结构体”技术的基本过程: ⑴ 针对具体的组合数据,定义专门的结构体数据类型; ⑵ 使用定义好的数据类型,定义要使用的结构体变量; ⑶ 使用定义的结构体变量表示有关数据。
一、结构体类型 结构体类型的定义 定义结构体类型的一般格式如下: Struct 结构体名 { 成员表 }; 如右边是对学生组合 数据的结构体类型 定义: struct student { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ };
一、结构体类型 结构体类型定义说明 ⑴ “结构体名”是用户定义的结 构体的名字,在以后定义结构体变 量时,使用该名字进行类型标识。 struct student { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ }; 结构体类型定义说明 ⑴ “结构体名”是用户定义的结 构体的名字,在以后定义结构体变 量时,使用该名字进行类型标识。 ⑵ “成员表”是对结构体数据中每一个数据项的变量说明,其格式与说明一个变量的一般格式相同,如下: 数据类型名 成员名; ⑶ “struct”是关键字,“struct 结构体名”是结构体类型标识符,在类型定义和类型使用时“struct”都不能省略。 ⑷ 结构体名称可以省略,此时定义的结构称为无名结构。 ⑸ 整个定义作为一个完整的语句用分号结束。 ⑹ 结构体成员名允许和程序中的其他变量同名,二者不会混淆。
一、结构体类型 struct date { int month; int day; int year; }; struct stud int num; char name[20]; char sex; int age; struct date birthday; char addr[30]; }stud1,stud2; 结构体的嵌套 C语言结构体成员的数据类型既可以是简单的数据类型,也可以是复杂的数据类型,成员也可以是一个结构体。当结构体的成员又是结构体时,称为结构体的嵌套。如右图 struct stud结构如下表所示。 num name sex age birthday addr month day year
二、结构体变量 结构体变量定义 ⑴ 先定义结构体类型, 再定义结构体变量。 一般格式如下: struct 结构体名称 结构变量名; struct student { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ }; struct student student1,student2; 结构体变量定义 ⑴ 先定义结构体类型, 再定义结构体变量。 一般格式如下: struct 结构体名称 结构变量名; 如上面已定义了一个结构体类型student,可以用它来定义变量: struct student student1,student2;
二、结构体变量 结构体变量定义 ⑵ 在定义结构体类型的同时 定义结构体变量。 一般格式如下: struct 结构体名 { 成员表 struct student { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ } student1,student2; 结构体变量定义 ⑵ 在定义结构体类型的同时 定义结构体变量。 一般格式如下: struct 结构体名 { 成员表 }结构体变量1, 结构体变量2,┅,结构体变量n;
二、结构体变量 结构体变量定义 ⑶ 不定义结构体类型名,直 接定义结构类型变量。 一般格式如下: struct { 成员表 int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ } student1,student2; 结构体变量定义 ⑶ 不定义结构体类型名,直 接定义结构类型变量。 一般格式如下: struct { 成员表 }结构体变量1, 结构体变量2,┅,结构体变量n;
二、结构体变量 结构体成员引用 结构作为若干成员的集合是 一个整体,但在使用结构时, 不仅要对结构整体进行操作, struct student { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ } student1,student2; 二、结构体变量 结构体成员引用 结构作为若干成员的集合是 一个整体,但在使用结构时, 不仅要对结构整体进行操作, 而且更多的是要访问结构中的每个成员。在程序中使用结 构体成员的方法为: 结构体变量名.成员名称 如,当使用student1变量的age成员时,用如下方式: student1.age “.”是结构体成员运算符,“.”操作的优先级在C语言中是最高的,其结合性为从左到右。
二、结构体变量 例13-1输入一个学生的一组数据,然后输出其姓名、年龄和地址。 main() {printf("Enter num,age,score:"); scanf("%d,%d,%f",&stu.num, &stu.age,&stu.score); printf("Enter name:"); getchar(); gets(stu.name); printf("Enter sex:"); scanf("%c",&stu.sex); printf("Enter address:"); gets(stu.addr); printf("name:%s,age:%d,address:", stu.name,stu.age); puts(stu.addr); } #include "stdio.h" struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu;
二、结构体变量 结构体变量初始化 一般形式如下: struct 结构体名 结构体变量={初始化数据}; struct student { long num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ } stu={990101,"liujia",'M',19,87.5,"shanghai"} ;
三、结构体数组 数组元素是结构体类型的数组,称为结构体数组。 结构体数组具有数组的一切性质: 数组元素具有相同的类型; 结构体数组中每个元素的起始下标从0开始; 数组名称表示该结构体数组的存储首地址; 结构体数组存放在一个连续的内存区域中,它所占内存数目为结构体类型的大小乘以数组元素的个数; 结构体数组名和数组的指针都可以作为函数的参数等。
三、结构体数组 结构体数组概述 定义方法: ⑴ 先定义结构体类型,然后用结构体类型定义数组变量。如: struct student information[100]; ⑵ 在定义结构体类型的同时,定义数组变量,该结构体类型可以是有名类型,也可以是无名类型。 如: struct date 或: struct { { int year,month,day; int year,month,day; }date1[10],date2[10]; }date1[10],date2[10];
三、结构体数组 结构体数组初始化 struct student info[3]={ {990101,"liujia",'M',19,87.5,"shanghai"}, {990102,"wangkai",'M',18,89.5,"beijing"}, {990103,"xiaohua",'F',20,81.0,"qingdao"}};
三、结构体数组 结构体数组的应用 例13-2 按照表13-1的数据情况,输入一个班级的学生信息,要求: ⑴ 分别统计出男生和女生人数。 ⑵ 把学习成绩在85以上的学生找出来,并输出这部分学生如下信息:姓名、成绩、地址。
三、结构体数组 for(i=0;i<N;i++) { if(stu[i].sex=='M'||stu[i].sex=='m') count_m++; else count_f++; if(stu[i].score>85) printf("name:%s,score:%d,address:%d", stu[i].name,stu[i].score,stu[i].addr); } printf("\nschoolboy=%d, schoolgirl=%d\n", count_m,count_f); #define N 10 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; main() {struct student stu[N]; int i,count_m=0,count_f=0; for(i=0;i<N;i++) { printf("Information No.%d:\n",i+1); printf(" Enter num,age,score:"); scanf("%d,%d,%f",&stu[i].num,&stu[i].age, &stu[i].score); printf(" Enter name:"); getchar(); gets(stu[i].name); printf(" Enter sex:"); scanf("%c",&stu[i].sex); printf(" Enter address:"); gets(stu[i].addr); }
四、结构体指针 结构体指针变量的定义及使用 定义结构体指针的一般形式: struct 结构体名 *结构体指针变量名; 例如,如已定义结构体类型struct student,则可用如下形式定义结构体指针变量: struct student *p,*q;
四、结构体指针 例13-4 结构体指针用法示例。 #include "stdio.h" #include "string.h" struct stud {char *number; char name[20]; int score; }; main() {struct stud student,*p; p=&student; p->number="991001"; strcpy(p->name,"changjiang"); student.score=91; printf("\n"); printf("student No.%s\nname:%s\nscore:%d\n", p->number,p->name,p->score); }
四、结构体指针 例13-5指向结构体数组指针的应用示例。 #include "stdio.h" struct stud { char *number; char name[20]; int score; }stu[3]={"990103","xiaohua",81, "990104","zhangli",82, "990105","wangfeng",88}; main() {struct stud *p; printf("\nstudent No.name score\n"); for(p=stu;p<stu+3;p++) printf("%-15s%-20s%4d\n",p->number, p->name,p->score); }
例13-7用一个结构体表示学生的学号和成绩,编写程序,对班中30名学生按成绩进行排序,并输出排序后的学号、成绩和全班平均成绩分。 四、结构体指针 #define N 10 struct stu_info {char num[6]; int score; }stu[N]; main ( ) {struct stu_info *pt,*p[N]; int i,j; float sum=0; for(i=0;i<N;i++) { fflush(stdin); gets(stu[i].num); scanf("%d",&stu[i].score); p[i]=&stu[i]; sum+=stu[i].score;} for(i=1;i<N;i++) {for (j=0;j<N-1;j++) if(p[j]->score<p[j+1]->score) { pt=p[j];p[j]=p[j+1]; p[j+1]=pt;} } for(i=0;i<N;i++) printf("%10s%d\n", p[i]->num,p[i]->score); printf ("average score=%d\n", sum/N);
四、结构体指针 结构体指针作函数的参数 例13-8 用结构体指针作函数的参数,改写例13-7的程序(删去成绩统计功能)。 #include "stdio.h" #define N 5 struct stu_info {char num[7]; int score; }stu[]={"990101",87, "990102",89, "990103",81, "990104",82, "990105",88}; main ( ) { void sort_stu(struct stu_info *,int); int i; sort_stu(stu,N); for(i=0;i<N;i++) printf("%-10s%d\n",stu[i].num, stu[i].score); } void sort_stu(struct stu_info *p,int n) {int i,j; struct stu_info temp; for(i=1;i<n;i++) {for (j=0;j<N-1;j++) if(p[j].score<p[j+1].score) { temp=p[j]; p[j]=p[j+1]; p[j+1]=temp;} }
五、共用体 共用体概述 共用体是有别于以前任何一种数据类型的特殊数据类型,它是多个成员的一个组合体,但与结构体不同,共用体的成员被分配在同一段内存空间中,它们的开始地址相同,使得同一段内存由不同的变量共享。共同使用这段内存的变量既可以具有相同的数据类型,也可以具有不同的数据类型。
五、共用体 共用体类型定义 一般形式如下: union 共用体名 { 数据类型 成员名1; union data 数据类型 成员名2; { …… 数据类型 成员名n; }; union data { int i; char ch; float f; };
五、共用体 共用体变量的定义 1.共用体类型与共用体变量同时定义 2.先定义共用体类型,再定义共用体变量 3.直接定义共用体变量 union data {int i; char ch; float f; }u1,u2,u3; union data {int i; char ch; float f; } ; union data u1,u2,u3; union {int i; char ch; float f; }u1,u2,u3;
五、共用体 共用体变量的引用 如:使用u5.i形式引用共用变量u5的成员i; 使用u5.ch形式引用共用变量u5的成员ch; 使用u5.f形式引用共用变量u5的成员f。 共用体数据特点 1.共用体变量中的值是最后一次存放的成员的值。 2.共用体变量不能初始化。 3.共用体变量的地址和它的各成员的地址都是同一个地址值,如&u1、&u.i、&u.ch、&u.f是相同的。
五、共用体 例16-1 分析以下程序的执行结果。 #include "stdio.h" union {long i; int k; char m; char s[4]; }part; main ( ) {part.i=0x12345678; printf("part.i=%lx\n",part.i); printf("part.k=%x\n",part.k); printf("part.m=%x\n",part.m); printf("part.s[0]=%x\t part.s[1]=%x\n",part.s[0],part.s[1]); printf("part.s[2]=%x\t part.s[3]=%x\n",part.s[2],part.s[3]); }
结构体和共用体-小结 作业:教材13.2 13.4 1.结构体是一种新型的数据类型: ⑴ 结构体数据类型不是系统固有的,它需要由用户自定义; ⑵ 一个结构体数据类型是多个具有不同类型的不同成员的集合。 2.“struct”是结构体数据类型的关键字。 3.结构体变量的定义有3种方法: 先定义结构体类型,再定义结构体变量; 在定义结构体类型的同时定义结构体变量; 不定义结构体类型名,直接定义结构类型变量。 4.引用结构体成员的方法主要有两种:使用结构体变量名引用结构体成员;通过指向结构体变量的指针引用结构体成员。 5.结构体数组具有数组的一切性质。 6.结构体指针既可以指向单一的结构体变量,也可以指向结构体数组变量,结构体指针也可以作函数的参数。 7.共用体是一种特殊的数据类型,它是多个成员的一个组合体,其本质是使多个变量共享同一段内存,共用体变量中的值是最后一次存放的成员的值,共用体变量不能初始化,共用体变量的长度是成员中最大长度值。 作业:教材13.2 13.4