《九章结构体和共用体.ppt》由会员分享,可在线阅读,更多相关《九章结构体和共用体.ppt(62页珍藏版)》请在三一文库上搜索。
1、第九章 结构体和共用体,本章介绍了C语言中的最后几种数据类型:结构体、共用体、位段以及如何使用typedef定义类型。其中结构体类型是重点,要求掌握定义、引用、初始化及应用等。结构体与指针的结合既是本章的重点又是难点。最后,介绍了内存的动态分配和单向链表的简单操作。,结构体 结构体型指针 共用体 用typedef定义类型,结构体型数组 内存的动态分配 位段 程序示例,结构体类型的定义,C语言提供的 结构体 类型,能将具有内在联系的不同类型的数据组合在一起,以便于处理。,结构体类型的定义形式: struct 结构体类型 成员表列; ;,例如: struct student long int nu
2、m; char name20; char sex; int age; ;,10001,Li Fang,M,18,num,name,sex,age,说明: (1) 关键字struct和结构体类型名组成一种类型标识符,类型名的起名规则遵从标识符。 (2)成员表列列出了本结构体类型所包含的若干个成员。,结构体类型变量的定义,要定义一个结构体类型的变量,可以采用以下三种方法: (1) 先定义类型在定义变量名。 示例 (2) 在定义类型的同时定义变量。示例 (3)直接定义结构体类型变量。 示例 说明: (1) 第一种定义形式最好,概念清楚,易于扩充移植。 (2) 结构体型变量所占内存空间是各成员变量所占
3、内存单元的总和,一般占一片连续单元。 (3)成员也可以是一个结构体变量 示例 (4)同一结构体类型中的各成员不可重名,但不同结构体类型间的各成员可以重名。,要定义一个结构体类型的变量,可以采用以下三种方法: (1) 先定义类型在定义变量名。 示例 (2) 在定义类型的同时定义变量。示例 (3)直接定义结构体类型变量。 示例 说明: (1) 第一种定义形式最好,概念清楚,易于扩充移植。 (2) 结构体型变量所占内存空间是各成员变量所占内存单元的总和,一般占一片连续单元。 (3)成员也可以是一个结构体变量 示例 (4)同一结构体类型中的各成员不可重名,但不同结构体类型间的各成员可以重名。,结构体类
4、型变量的定义,struct student long int num; char name20; char sex; int age; ; struct student stu1, stu2;,要定义一个结构体类型的变量,可以采用以下三种方法: (1) 先定义类型在定义变量名。 示例 (2) 在定义类型的同时定义变量。示例 (3)直接定义结构体类型变量。 示例 说明: (1) 第一种定义形式最好,概念清楚,易于扩充移植。 (2) 结构体型变量所占内存空间是各成员变量所占内存单元的总和,一般占一片连续单元。 (3)成员也可以是一个结构体变量 示例 (4)同一结构体类型中的各成员不可重名,但不同结
5、构体类型间的各成员可以重名。,结构体类型变量的定义,struct student long int num; char name20; char sex; int age; stu1, stu2;,要定义一个结构体类型的变量,可以采用以下三种方法: (1) 先定义类型在定义变量名。 示例 (2) 在定义类型的同时定义变量。示例 (3)直接定义结构体类型变量。 示例 说明: (1) 第一种定义形式最好,概念清楚,易于扩充移植。 (2) 结构体型变量所占内存空间是各成员变量所占内存单元的总和,一般占一片连续单元。 (3)成员也可以是一个结构体变量 示例 (4)同一结构体类型中的各成员不可重名,但不
6、同结构体类型间的各成员可以重名。,结构体类型变量的定义,struct long int num; char name20; char sex; int age; stu1, stu2;,结构体类型变量的定义,要定义一个结构体类型的变量,可以采用以下三种方法: (1) 先定义类型在定义变量名。 示例 (2) 在定义类型的同时定义变量。示例 (3)直接定义结构体类型变量。 示例 说明: (1) 第一种定义形式最好,概念清 楚,易于扩充移植。 (2) 结构体型变量所占内存空间是各成员变量所占内存单元的总和,一般占一片连续单元。 (3)成员也可以是一个结构体变量 示例 (4)同一结构体类型中的各成员不
7、可重名,但不同结构体类型间的各成员可以重名。,struct date int month; int day; int year; ; struct student long int num; char name20; char sex; int age; struct date birthday; stu1, stu2;,结构体型变量及其成员的引用,结构体型变量可引用的对象:变量名(代表变量的整体),成员名 (代表变量的各个成员)。 引用时注意: (1) 变量成员的引用方法:结构体变量名 . 成员名 如 stu1.num, stu1.name stu1.birthday.month (2) 结
8、构体型变量可以整体引用来赋值,如stu1=stu2。但不可以进行整体的输入 输出,如 printf( “%s”, stu1); 是错误的 (3) 结构体型变量的首地址称为该结构体型变量的地址,其每个成员的首地址称 为该成员的地址,两个地址均可引用。如: scanf( “%d”, /*输出结构体变量的首地址*/,结构体型变量的初始化,结构体型变量的初始化,即直接以初值表的形式赋值。如: stu1,stu2的初始化: struct student stu1=99001,“Wang lin“.M,21; struct student stu2=99002,“Liu Dong“,F,19; 所有结构体
9、型变量均可如此初始化。,例1:利用结构体类型,编程计算一名同学5门课的平均分。 例2:将上例改为输入任意多人5门课的成绩,求平均分。,例 1:利用结构体类型,编程计算一名同学5门课的平均分,void main( ) struct stuscore char name20; float score5; float average; ; struct stuscore x=“Wang wei“, 90.5,85,70,90,98.5; int i; float sum=0; for(i=0;i5;i+) sum+=x.scorei; x.average=sum/5; printf( “The av
10、erage score of %s is %4.1fn”, x.name, x.average); ,运行结果:,定义结构体类型,void main( ) struct stuscore char name20; float score5; float average; ; struct stuscore x=“Wang wei“, 90.5,85,70,90,98.5; int i; float sum=0; for(i=0;i5;i+) sum+=x.scorei; x.average=sum/5; printf( “The average score of %s is %4.1fn”,
11、x.name, x.average); ,运行结果:,&x,定义结构体类型变量,并初始化,例 1:利用结构体类型,编程计算一名同学5门课的平均分,void main( ) struct stuscore char name20; float score5; float average; ; struct stuscore x=“Wang wei“, 90.5,85,70,90,98.5; int i; float sum=0; for(i=0;i5;i+) sum+=x.scorei; x.average=sum/5; printf( “The average score of %s is %
12、4.1fn”, x.name, x.average); ,运行结果:,&x,计算5门课的总分,例 1:利用结构体类型,编程计算一名同学5门课的平均分,void main( ) struct stuscore char name20; float score5; float average; ; struct stuscore x=“Wang wei“, 90.5,85,70,90,98.5; int i; float sum=0; for(i=0;i5;i+) sum+=x.scorei; x.average=sum/5; printf( “The average score of %s is
13、 %4.1fn”, x.name, x.average); ,运行结果:,&x,计算5门课的平均分,例 1:利用结构体类型,编程计算一名同学5门课的平均分,void main( ) struct stuscore char name20; float score5; float average; ; struct stuscore x=“Wang wei“, 90.5,85,70,90,98.5; int i; float sum=0; for(i=0;i5;i+) sum+=x.scorei; x.average=sum/5; printf( “The average score of %s
14、 is %4.1fn”, x.name, x.average); ,运行结果: The average score of Wang wei is 86.8,&x,输出结果,例 1:利用结构体类型,编程计算一名同学5门课的平均分,#include void main( ) struct stuscore char name20; float score5; float average; x; int i; float sum; char rep; while(1) printf( “n Do you want to continue? (Y/N)”); rep=getche( ); if(rep
15、 = = n | rep = = N) break;,sum=0; printf( “n Input name(as XU_jun) and 5 scores(depart by ):n”); scanf( “%s”, x.name); for(i=0; i5; i+) scanf( “%f”, ,例 2:将上例改为输入任意多人5门课的成绩,求平均分。,运行结果:,#include void main( ) struct stuscore char name20; float score5; float average; x; int i; float sum; char rep; while
16、(1) printf( “n Do you want to continue? (Y/N)”); rep=getche( ); if(rep = = n | rep = = N) break;,sum=0; printf( “n Input name(as XU_jun) and 5 scores(depart by ):n”); scanf( “%s”, x.name); for(i=0; i5; i+) scanf( “%f”, ,例 2:将上例改为输入任意多人5门课的成绩,求平均分。,运行结果: Do you want to continue?(Y/N),#include void ma
17、in( ) struct stuscore char name20; float score5; float average; x; int i; float sum; char rep; while(1) printf( “n Do you want to continue? (Y/N)”); rep=getche( ); if(rep = = n | rep = = N) break;,sum=0; printf( “n Input name(as XU_jun) and 5 scores(depart by ):n”); scanf( “%s”, x.name); for(i=0; i5
18、; i+) scanf( “%f”, ,例 2:将上例改为输入任意多人5门课的成绩,求平均分。,运行结果: Do you want to continue?(Y/N) Y,#include void main( ) struct stuscore char name20; float score5; float average; x; int i; float sum; char rep; while(1) printf( “n Do you want to continue? (Y/N)”); rep=getche( ); if(rep = = n | rep = = N) break;,s
19、um=0; printf( “n Input name(as XU_jun) and 5 scores(depart by ):n”); scanf( “%s”, x.name); for(i=0; i5; i+) scanf( “%f”, ,例 2:将上例改为输入任意多人5门课的成绩,求平均分。,运行结果: Do you want to continue?(Y/N) Y Input name(as Xu_jun) and 5 scores(depart by):,#include void main( ) struct stuscore char name20; float score5;
20、float average; x; int i; float sum; char rep; while(1) printf( “n Do you want to continue? (Y/N)”); rep=getche( ); if(rep = = n | rep = = N) break;,sum=0; printf( “n Input name(as XU_jun) and 5 scores(depart by ):n”); scanf( “%s”, x.name); for(i=0; i5; i+) scanf( “%f”, ,例 2:将上例改为输入任意多人5门课的成绩,求平均分。,运
21、行结果: Do you want to continue?(Y/N) Y Input name(as Xu_jun) and 5 scores(depart by): Guo_Yong 80 89.5 99 87.5,#include void main( ) struct stuscore char name20; float score5; float average; x; int i; float sum; char rep; while(1) printf( “n Do you want to continue? (Y/N)”); rep=getche( ); if(rep = =
22、n | rep = = N) break;,sum=0; printf( “n Input name(as XU_jun) and 5 scores(depart by ):n”); scanf( “%s”, x.name); for(i=0; i5; i+) scanf( “%f”, ,例 2:将上例改为输入任意多人5门课的成绩,求平均分。,运行结果: Do you want to continue?(Y/N) Y Input name(as Xu_jun) and 5 scores(depart by): Guo_Yong 80 89.5 99 87.5 Do you want to co
23、ntinue?(Y/N),#include void main( ) struct stuscore char name20; float score5; float average; x; int i; float sum; char rep; while(1) printf( “n Do you want to continue? (Y/N)”); rep=getche( ); if(rep = = n | rep = = N) break;,sum=0; printf( “n Input name(as XU_jun) and 5 scores(depart by ):n”); scan
24、f( “%s”, x.name); for(i=0; i5; i+) scanf( “%f”, ,例 2:将上例改为输入任意多人5门课的成绩,求平均分。,运行结果: Do you want to continue?(Y/N) Y Input name(as Xu_jun) and 5 scores(depart by): Guo_Yong 80 89.5 99 87.5 Do you want to continue?(Y/N) N,结构体型数组,数组中的元素为结构体型数据,在构造树、表、队列等数据结构时尤其方便。结构体型数组的定义:和结构体变量的方法相仿,只需说明其为数组即可。如 struc
25、t student stu5; 结构体型数组的初始化: 初始化形式是定义数组时,后面加上=初值列表,如: struct student stu2=99001, “Wang Jian”, F, 20, 99002, “Liu Li”, M, 19 ; 示例:用结构体型数组初始化建立一工资登记表,然后键入其中一人的 姓名,查询其工资情况。,结构体数组示例,例 3:用结构体数组初始化建立一工资登记表,键入其中一人姓名,查询其工资情况。,int i; char xname20; printf(“nInput the workers name: “); Scanf(“%s“, xname); for(i
26、=0;i3;i+) if(strcmp(xname,workeri.name)=0) printf(“*%s*“,xname); printf(“nsalary:%6d“,workeri.salary); printf(“ncost:%6d“,workeri.cost); printf(“npayed:%6dn“,workeri.salary- workeri.cost); ,#include void main( ) struct staff char name20; char departmet20; int salary; int cost; worker3= “Xu_Guo“, “pa
27、rt1“, 800, 200, “Wu_Xia“, “part2“, 1000, 300, “Li_Jun“, “part3“, 1200, 350 ;,结构体数组示例,例 3:用结构体数组初始化建立一工资登记表,键入其中一人姓名,查询其工资情况。,运行结果: Input the workers name: Wu_Xia,int i; char xname20; printf(“nInput the workers name: “); Scanf(“%s“, xname); for(i=0;i3;i+) if(strcmp(xname,workeri.name)=0) printf(“*%s*
28、“,xname); printf(“nsalary:%6d“,workeri.salary); printf(“ncost:%6d“,workeri.cost); printf(“npayed:%6dn“,workeri.salary- workeri.cost); ,#include void main( ) struct staff char name20; char departmet20; int salary; int cost; worker3= “Xu_Guo“, “part1“, 800, 200, “Wu_Xia“, “part2“, 1000, 300, “Li_Jun“,
29、 “part3“, 1200, 350 ;,结构体数组示例,运行结果: Input the workers name: Wu_Xia *Wu_Xia* salary: 1000 cost: 300 payed: 700,例 3:用结构体数组初始化建立一工资登记表,键入其中一人姓名,查询其工资情况。,#include void main( ) struct staff char name20; char departmet20; int salary; int cost; worker3= “Xu_Guo“, “part1“, 800, 200, “Wu_Xia“, “part2“, 1000,
30、 300, “Li_Jun“, “part3“, 1200, 350 ;,int i; char xname20; printf(“nInput the workers name: “); Scanf(“%s“, xname); for(i=0;i3;i+) if(strcmp(xname,workeri.name)=0) printf(“*%s*“,xname); printf(“nsalary:%6d“,workeri.salary); printf(“ncost:%6d“,workeri.cost); printf(“npayed:%6dn“,workeri.salary- worker
31、i.cost); ,结构体指针,一个结构体变量的指针就是该变量所占据的内存段的起始地址。 引入结构体型指针的目的: 下面从以下三个内容详细介绍结构体型指针:,(1)结构体指针作为函数的参数传递数据非常有效; (2)结构体型数组的指针可以提高数组的访问效率; (3)可以建立动态的数据结构,动态地、合理地分配内存。 指向结构体变量的指针 指向结构体型数组的指针 用指向结构体型的指针作函数参数,指向结构体变量的指针,定义格式是: 在定义结构体变量的同时,定义一指针。 如: struct stuednt stu,*p; 若执行了语句 p= 则:(如右图) 此后,程序可通过指针p来引用stu1的成员。
32、结构体成员的引用方式有三种: 示例 (1) 结构体变量.成员名 (2) (*p).成员名 (3) p-成员名 注意:以下表达式的含义(-的优先级高于+) p-n 得到成员n的值 p-n+ 得到成员n的值,用完该值后使它加1 +p-n 得到成员n的值使之加1(先加),p,例 4:结构体成员的三种引用方式,void main( ) struct staff char name20; char department20; int salary; ; struct staff w1,*p; p= ,运行结果: Li_Li part1 1000 Li_Li part1 1000 Li_Li part1
33、1000,void main( ) struct staff char name20; char department20; int salary; ; struct staff w1,*p; p= ,例 4:结构体成员的三种引用方式,指向结构体型数组的指针,结构体数组可用指针来访问,方便数组元素的引用,提高数组的访问效率。 示例: 用指向结构体型数组的指针实现显示工资表的程序 注意: (1) 如果p的初值为worker,即指向第一个元素,则p+1后指向下一个元素的起始地址。 例如: (+p)-name 先使p自加1,然后得到它指向的元素中的name成员值。 (p+)-name 先得到p-na
34、me的值,然后使p自加1,指向worker1. (2) 指针p已定义指向struct staff类型的数据,它只能指向一个结构体型数组,而不能指向元素中的某一成员。,p,p+1,worker,&worker0,&worker1,&worker2,例 5:利用结构体型指针显式工资表,struct staff char name20; int salary; ; void main( ) struct staff *p; struct staff worker3=“Wang_Li“, 600, “Li_Ping“, 700, “Liu_Yuan“, 800; for(p=worker;pname,
35、 p-salary); ,运行结果: Wang_Lis salary is 600 yuan Li_Pings salary is 700 yuan Liu_Yuans salary is 800 yuan,p,p+1,worker,&worker0,&worker1,&worker2,例 5:利用结构体型指针显式工资表,struct staff char name20; int salary; ; void main( ) struct staff *p; struct staff worker3=“Wang_Li“, 600, “Li_Ping“, 700, “Liu_Yuan“, 800
36、; for(p=worker;pname, p-salary); ,用指向结构体型的指针作函数参数,若想将一个结构体变量的值传递给另一个函数,可以: (1) 用结构体变量作为函数实参,将结构体变量所占内存单元的内容全部顺序传递给形参。 (2) 用指向结构体变量(或数组)的指针作实参。将结构体变量(或数组)的地址传递给形参。则形参、实参共用一段存储空间。 例 6:用子函数求出worker数组中每个工人的实发工资 例 7:有四个学生,每个学生包括学号、姓名、成绩。要求找出成绩最高者 的姓名和成绩。,例 6:用子函数求每个工人的实发工资,#include #define NUM 2 struct s
37、taff char name20; char department20; int salary; int cost; int realsum; ; void getreal(struct staff *p, int n) int i; for(i=0;irealsum=p-salary=p-cost; ,void main( ) struct staff workerNUM, *pm; int i; printf(“Input %d workers name department salary cost: n“, NUM); for(i=0, pm=worker; iname, pm-depa
38、rtment, pm-salary, pm-cost); pm=worker; getreal(pm, NUM); for(pm=worker; pmname, pm-department, pm-realsum); ,运行结果: Input 2 workers name deparment salary cost:,#include #define NUM 2 struct staff char name20; char department20; int salary; int cost; int realsum; ; void getreal(struct staff *p, int n
39、) int i; for(i=0;irealsum=p-salary=p-cost; ,void main( ) struct staff workerNUM, *pm; int i; printf(“Input %d workers name department salary cost: n“, NUM); for(i=0, pm=worker; iname, pm-department, pm-salary, pm-cost); pm=worker; getreal(pm, NUM); for(pm=worker; pmname, pm-department, pm-realsum);
40、,例 6:用子函数求每个工人的实发工资,运行结果: Input 2 workers name deparment salary cost: Wang part1 1000 200 Liu part2 1500 300,#include #define NUM 2 struct staff char name20; char department20; int salary; int cost; int realsum; ; void getreal(struct staff *p, int n) int i; for(i=0;irealsum=p-salary=p-cost; ,void ma
41、in( ) struct staff workerNUM, *pm; int i; printf(“Input %d workers name department salary cost: n“, NUM); for(i=0, pm=worker; iname, pm-department, pm-salary, pm-cost); pm=worker; getreal(pm, NUM); for(pm=worker; pmname, pm-department, pm-realsum); ,例 6:用子函数求每个工人的实发工资,运行结果: Input 2 workers name depa
42、rment salary cost: Wang part1 1000 200 Liu part2 1500 300 Wang of part1 should be payed 800 yuan Liu of part2 should be payed 1200 yuan,#include #define NUM 2 struct staff char name20; char department20; int salary; int cost; int realsum; ; void getreal(struct staff *p, int n) int i; for(i=0;irealsu
43、m=p-salary=p-cost; ,void main( ) struct staff workerNUM, *pm; int i; printf(“Input %d workers name department salary cost: n“, NUM); for(i=0, pm=worker; iname, pm-department, pm-salary, pm-cost); pm=worker; getreal(pm, NUM); for(pm=worker; pmname, pm-department, pm-realsum); ,例 6:用子函数求每个工人的实发工资,void
44、 main( ) struct student int num; char name20; float score; ; struct student stu4,*p; int i,temp=0; float max; for(i=0;imax) max=stui.score;temp=i; p=stu+temp; printf(“nThe maximum score:n“); printf(“No.:%dnname:%snscore:%4.1fn“, p-num, p-name, p-score); ,stu,p, stu+1,例 7:找出四个学生中成绩最高者的姓名和成绩,stu,p, st
45、u+1,运行结果: 101 Li 90,例 7:找出四个学生中成绩最高者的姓名和成绩,void main( ) struct student int num; char name20; float score; ; struct student stu4,*p; int i,temp=0; float max; for(i=0;imax) max=stui.score;temp=i; p=stu+temp; printf(“nThe maximum score:n“); printf(“No.:%dnname:%snscore:%4.1fn“, p-num, p-name, p-score);
46、 ,stu,p, stu+1,运行结果: 101 Li 90 102 Tan 98,例 7:找出四个学生中成绩最高者的姓名和成绩,void main( ) struct student int num; char name20; float score; ; struct student stu4,*p; int i,temp=0; float max; for(i=0;imax) max=stui.score;temp=i; p=stu+temp; printf(“nThe maximum score:n“); printf(“No.:%dnname:%snscore:%4.1fn“, p-num, p-name, p-score); ,stu,p, stu+1,运行结果: 101 Li 90 102 Tan 98 103 Wang 67,例 7:找出四个学生中成绩最高者的姓名和成绩,void main( ) struct student int num; char name20; float score; ; struct student stu4,*p; int i,temp=0; floa