《C语言第9章的课件.ppt》由会员分享,可在线阅读,更多相关《C语言第9章的课件.ppt(65页珍藏版)》请在三一文库上搜索。
1、1,第9章 用户建立的数据类型,2,本章要求,掌握结构体类型的概念和定义,结构体变量、结构体数组及结构体变量指针的定义,成员运算符与结构体变量的引用; 掌握共用体类型的概念、定义及应用; 掌握枚举类型的概念、定义及应用; 会用typedef定义类型。,3,9.1 结构体类型和结构体变量,4,迄今为止,已介绍了基本类型(或称简单类型)的变量(如整型、实型、字符型变量等),也介绍了一种构造类型数据数组,数组中的各元素是属于同一个类型的。但是只有这些数据类型是不够的。有时需要将不同类型的数据组合成一个有机的整体,以便于引用。这些组合在一个整体中的数据是互相联系的。例如,一个学生的学号、姓名、性别、年
2、龄、成绩、家庭地址等项。这些项都与某一学生相联系。见图9.1。可以看到性别(sex)、年龄(age)、成绩(score)、地址(addr)是属于学号为10010和名为“Li Fun”的学生的。如果将num、name、sex、age、score、addr分别定义为互相独立的简单变量,难以反映它们之间的内在联系。,9.1.1 结构体类型,5,应当把它们组织成一个组合项,在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。C语言允许用户自己指定这样一种数据结构,它称为结构体(structure)。它相当于其他高级语言中的“记录”。,结构体类型属于C语言的一种组合数据类型。 结构体能将不同类型
3、的数据封装在一起,成为一个整体。 在定义结构体变量时,要先对结构体的结构进行声明。然后才能用该结构体类型定义变量。,6,结构体结构声明格式: struct 结构体名 成员列表; 结构体变量的一般定义格式: struct 结构体名 变量名; 例: struct student int num; char name20; char sex; int age; float score; char addr30; ;,此处必须加分号,7,9.1.2 定义结构体类型变量,1. 先声明结构体类型再定义变量名。 如上面已定义了一个结构体类型struct student,可以用它来定义变量。如: struct
4、 student student1, student2; (结构体类型名) (结构体变量名) 定义了student1和student2为struct student类型的变量,即它们具有struct student类型的结构。,8,在定义了结构体变量后,系统会为之分配内存单元。例如student1和student2在内存中各占59个字节(2+20+1+2+4+30=59)。,9,2. 在声明类型的同时定义变量。 例如: struct student int num; char name20; char sex; int age; float score; char addr30; studen
5、t1,student2; 它的作用与第一种方法相同,即定义了两个struct student类型的变量student1、student2。,10,3. 直接定义结构类型变量 其一般形式为 struct 成员表列 变量名表列; 即不出现结构体名。,11,说明,(1) 类型与变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。 (2) 对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。 (3) 成员也可以是一个结构体变量。 (4) 成员名可以与程序中的变量名相同,二者不代表同一对象。例如
6、,程序中可以另定义一个变量num,它与struct student中的num是两回事,互不干扰。,12,如: struct date /*声明一个结构体类型*/ int month; int day; int year; ; struct student int num; char name20; char sex; int age; struct date birthday; /*birthday是struct date类型*/ char addr30; student1,student2;,13,9.1.3 引用结构体变量,在定义了结构体变量以后,当然可以引用这个变量。但应遵守以下规则:
7、(1) 不能将一个结构体变量作为一个整体进行输入和输出。例如,已定义student1和student2为结构体变量并且它们已有值。不能这样引用: printf (“%d,%s,%c,%d,%f,%sn“,student1); 只能对结构体变量中的各个成员分别进行输入和输出。引用结构体变量中成员的方式为 结构体变量名.成员名,14,例如: student1.num=10010; “.”是成员(分量)运算符,它在所有的运算符中优先级最高,因此可以把student 1.num作为一个整体来看待。上面赋值语句的作用是将整数10010赋给student 1变量中的成员num。,15,struct dat
8、e int year; int month; int day; ; main() struct date d; printf(“Enter todays date(yyyy-mm-dd):“); scanf(“%d-%d-%d“, ,运行,从键盘输入一个时间并输出,16,(2) 如果成员本身又属一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。例如,对上面定义的结构体变量student1, 可以这样访问各成员: student1.num student1.birthday.month 注意:不能用student1.birthday
9、来访问student1变量中的成员birthday,因为birthday本身是一个结构体变量。,17,(3) 对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。例如: student2.score=student1.score; sum=student1.score+student2.score; student1.age+; +student1.age; 由于“.”运算符的优先级最高,因此student1.age+是对student1.age进行自加运算,而不是先对age进行自加运算。,18,(4) 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。
10、如:scanf(“%d“, (输入student1.num的值) printf(“%o“,&student1); (输出student1的首地址)但不能用以下语句整体读入结构体变量,如: scanf(“%d,%s,%c,%d,%f,%s“,&student1); 结构体变量的地址主要用于作函数参数,传递结构体的地址。,19,(5) C程序中相同结构体类型的两个结构体变量间,可以整体赋值。 struct person p1,p2; . p1=p2;/*将结构体变量p2的所有成员值赋值给结构体变量p1的对应成员*/ .,20,9.1.4 结构体变量的初始化,和其他类型变量一样,对结构体变量可以在定
11、义时指定初始值。 例9.1对结构体变量初始化。 注意:各初值的类型和顺序必需和结构体各成员对应一致。,21,main() struct student long int num; char name20; char sex; char addr20; a=10101,“Li Lin”,M,“123 Beijing Road”; printf(“NO.:%ldnname:%snsex:%cnaddress:%sn“,a.num,a.name,a.sex,a.addr); ,定义并初始化结构体变量,22,9.2 结构体数组,23,结构体数组是结构体类型变量的存储序列。 struct penson
12、p10; 定义结构体数组p,p中每个元素都是同类型的结构体变量。 结构体数组的初始化。 struct person p10=“Wang Ling“,18,.,“Li Ming“,20,.,24,结构体数组的引用。 pi.age=22; 给结构体数组元素pi的成员age赋值22 例: # include “stdlib.h“ # include “stdio.h“ struct stud_type char name20; long num; int age; char sex; float score; ;,25,main() struct stud_type student3; int i;
13、 char ch; char numstr20; for(i=0;i3;i+) printf(“nenter all data of student%d:n“,i); gets(studenti.name); gets(numstr); studenti.num=atol(numstr); gets(numstr); studenti.age=atoi(numstr); studenti.sex=getchar(); ch=getchar(); gets(numstr); studenti.score=atof(numstr); printf(“nrecord name tt num age
14、sex scoren“); for(i=0;i3;i+) printf(“%3d%-20s%8ld%6d%3c%6.2fn“,i, studenti.name,studenti.num,studenti.age, studenti.sex,studenti.score); ,运行,26,9.3 结构体指针,27,一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素。,28,#include main() struct student long num; char n
15、ame20; char sex; float score; struct student stu_1; struct student * p; p= ,结构体指针的应用,29,(*p).num这样的形式。(*p)表示p指向的结构体变量,(*p).num是p指向的结构体变量中的成员num。注意*p两侧的括弧不可省,因为“.”优先于“*”运算符,*p.num就等价于*(p.num)了。,30,在C语言中,为了使用方便和使之直观,可以把(*p).num改用pnum来代替,它表示*p所指向的结构体变量中的num成员。同样,(*p).name等价于pname。也就是说,以下三种形式等价: 结构体变量成员
16、名 (*p).成员名 p-成员名 上面程序中最后一个printf函数中的输出项表列可以改写为p-num,p-name,p-sex,p-score 其中-称为指向运算符。,31,几个易混淆的表达式,p-n,得到p指向的结构体变量中的成员n的值。 p-n+,得到p指向的结构体变量中的成员n的值,用完该值后n加1。 +p-n,得到p指向的结构体变量中的成员n的值使之加1(先加)。 (+p)-n,p先加1,再做箭头运算,32,指向结构体数组的指针,定义一个结构体指针变量,就可以让其指向一个一维的结构体数组,通过它可对数组中的元素进行操作。 # include “stdlib.h“ # include
17、“stdio.h“ struct stud_type char name20; long num; int age; char sex; float score; ;,33,main() struct stud_type student3,*p; int i; char numstr20; for(i=0,p=student;pname); gets(numstr); p-num=atol(numstr); gets(numstr); p-age=atoi(numstr); p-sex=getchar(); getchar(); gets(numstr); p-score=atof(numst
18、r); printf(“nrecord namett num age sex scoren“); for(i=0,p=student;pname, p-num,p-age,p-sex,p-score); ,运行,34,结构体变量及结构体指针作函数参数,结构体变量和指针都可作函数参数,但实参和形参必需有相同的结构体类型。 结构体变量作函数参数时,传递的是变量各成员的值。结构体指针变量作函数参数时,传递的是结构体变量的地址。,35,用结构体变量作函数形参: void list1(struct stud_type student) printf(“%-20s%8ld%6d%3c%6.2fn“, st
19、udent.name, student.num,student.age,student.sex,student.score); 用结构体指针变量作函数形参: void list2(struct stud_type *p_s) printf(“%-20s%8ld%6d%3c%6.2fn“, p_s-name, p_s-num,p_s-age,p_s-sex,p_s-score); ,36,main() struct stud_type student3; int i; char ch; char numstr20; for(i=0;i3;i+) printf(“nenter all data o
20、f student%d:n“,i); gets(studenti.name); gets(numstr); studenti.num=atol(numstr); gets(numstr); studenti.age=atoi(numstr); studenti.sex=getchar(); ch=getchar(); gets(numstr); studenti.score=atof(numstr); printf(“nrecord name tt num age sex scoren“); for(i=0;i3;i+) list1(studenti); 或 list2( ,运行,37,返回结
21、构体类型值的函数,ANSI C标准允许一个函数返回结构体类型的值。该函数的返回值可以赋值给一个同类型的结构体变量。,38,struct srud_type new_element(void) struct stud_type student; char ch; char numstr20; printf(“nenter all data of student:n“); gets(student.name); gets(numstr); student.num=atol(numstr); gets(numstr); student.age=atoi(numstr); student.sex=ge
22、tchar(); ch=getchar(); gets(numstr); student.score=atof(numstr); return (student); ,39,main() struct stud_type student3; int i; for(i=0;i3;i+) printf(“nenter all data of student%d:n“,i); studenti= new_element(void); printf(“nrecord name tt num age sex scoren“); for(i=0;i3;i+) list1(studenti); ,运行,40
23、,9.5 共用体类型,41,共用体类型也叫联合类型,它是C语言的一种构造数据类型。 和结构体类型一样,共用体类型能将不同类型数据封装在一起,但其成员共存于同一段内存单元。 共用体数据类也必须先进行类型结构说明,然后才能定义变量。,42,共用体结构声明格式: union 共用体名 成员列表; 共用体变量定义格式: 格式1:union 共用体名 变量名; 格式2: union 共用体名 成员列表 变量名; 格式3:union 成员列表 变量名;,43,union exam int a; float b; char c; x;/*声明共用体数据类型exam,及定义该类型变量x*/,x,c,a,b,共
24、4字节,共用体变量的成员共占同一段内存空间,各成员的首地址相同。各成员不能同时存在。 共用体变量的存储空间大小是以其成员中所占空间最大的相同。,44,共用体变量的引用,共用体变量成员引用格式: 共用体变量名.成员,45,union exam int a; float b; char c; x; x.a=3;/*给共用体变量x的成员a赋值3*/ x.b=4.5;/*给成员b赋值4.5,a 的值被取代*/ x.c=A;/*给成员c赋值A,b 的值被取代*/ 由于成员a,b,c的存储空间是同一段,因此上例执行后,存储空间第一个单元的值是A。,46,共用体指针变量的定义: 共用体类型名 *指针变量 通
25、过共用体指针变量引用成员的方法: (*指针变量).成员 指针变量-成员 同结构体一样,共用体也不能作为整体进行输入输出。 同类型的共用体变量间可相互赋值。 函数可以返回共用体类型。 共用体类型也可作为函数参数。 可以定义共用体类型的数组。,47,共用体变量的应用,struct long num; char name20; char sex; char job; union int class; char group20; category; person10;,48,main() union int_char int i; char ch2; x; x.i=24897;/*24897的二进制是
26、0110,0001,0100,0001*/ printf(“i=%on“,x.i); printf(“ch0=%o,ch1=%onch0=%c,ch1=%cn“, x.ch0,x.ch1,x.ch0,x.ch1); ,x,x.i,x.ch0,x.ch1,共用体变量x的存储示意图(二进制),运行,49,union int_char int i; char ch2; ; main( ) union int_char y; void int_to_char(union int_char x); y.i=24897; int_to_char(y); void int_to_char(union int
27、_char x) printf(“i=%on“,x.i); printf(“ch0=%o,ch1=%onch0=%c,ch1=%cn“, x.ch0,x.ch1,x.ch0,x.ch1); ,运行,共用体作函数参数,50,union int_char int i; char ch2; ; main() union int_char y,*p; void int_to_char(union int_char *p); y.i=24897; p= ,运行,共用体指针作函数参数,51,9.6 枚举类型,52,枚举类型是指该类型变量只能从若干指定的值(枚举常量)中取值。 枚举类型定义格式: enum
28、枚举类型名枚举常量列表; 枚举变量定义格式: enum 枚举类型名 变量名;,53,enum color_name red,yellow,blue,white,black; enum color_name color;/*定义枚举类型变量color*/ 枚举变量color只能在枚举常量:red,yellow,blue,white,black中取值。 枚举常量不是字符串,不能用双引号括起。它只是程序中规定的一些标识符。,54,枚举变量赋值。 enum color_name red,yellow,blue,white,black; enum color_name color;/*定义枚举类型变量c
29、olor*/ color=red; color=white; color=green;/*错误,枚举常量列表中没有green*/ 枚举变量只能在指定枚举常量范围内取值。,55,枚举类型说明,和结构体一样,枚举类型必须先进行类型说明,才能定义该类型变量。 枚举常量按C标识符命名原则命名,它只是一些符号,对机器无意义。 枚举常量在编译时,按顺序被编译器用整型数0,1.依次代表。 程序中不能给枚举常量赋值。 如:red=0;/*错误*/ 枚举常量可以输出。 printf(“%d“,yellow);/*输出1*/,56,枚举常量可以进行关系比较。 如:redblue;/*表达式值为1*/ 枚举变量可进
30、行算术运算。 color=red; color+;/*color的值为yellow*/ 枚举常量不能用字符格式输出。 如:printf(“%d“,red);/*错误*/ 可以定义枚举指针和枚举数组。 定义枚举类型时,可指定枚举常量的初值。 enum color_name red=3,yellow,blue,white=8,black; /*red值为3,yellow值为4,blue值为5,white值为8,black值为9*/,57,枚举应用例子,口袋中有红、黄、蓝、白、黑5种颜色的球若干。每次从口袋中取出3个球,然后放回去。问可能取出的3种颜色组合有哪些。,58,enum colorred,
31、yellow,blue,white,black;/*声明表示颜色的枚举类型*/ main( ) void printcolor(enum color x); enum color i,j,k; int n=0; for (i=red;i=black;i+) for (j=red;j=black;j+) if (i=j) continue; for (k=red;k=black;k+) if (i=k|j=k) continue; printf(“%d:“,+n); printcolor(i); printcolor(j); printcolor(k); printf(“n“); ,59,voi
32、d printcolor(enum color x) switch (x) case red: printf(“%-10s“,“red“);break; case yellow: printf(“%-10s“,“yellow“);break; case blue: printf(“%-10s“,“blue“);break; case white: printf(“%-10s“,“white“);break; case black: printf(“%-10s“,“black“); ,运行,60,9.7 用typedef命名类型,61,在C程序中可用关键字typedef来定义新的类型名代替已有的
33、类型名。 例:typedef int INTEGER;/*定义int的新类名INTEGER*/ INTEGER i,j;/*定义整型变量i,j。相当于:int i,j;*/,62,说明,typedef用来定义新的类型名,不能用来定义变量。 typedef只能给已有的类型定义新类型名。不能用来建立如结构体、共用体、枚举等类型。 typedef的使用可提高程序可读性和移植性。,63,typedef struct char name20; long num; float score; STUDENT;/*定义结构体类型STUDENT*/ STUDENT stu1,stu2;/*定义结构体变量stu1,stu2*/ typedef int COUNT20;/*定义新数组类型COUNT*/ COUNT a,b;/*定义整型数组a,b*/ 等价于:int a20,b20;,64,typedf定义新类型的方法,1. 先按定义变量的方法写出定义体。 如:char name20; 2. 将变量名换成新类型名。 如:char NAME20; 3. 在最前面加上typedef。 如:typedef char NAME20; 4. 然后用新类型名定义变量。 如:NAME a,b;,65,本章作业,P281-282 1、2、5、,
链接地址:https://www.31doc.com/p-3479735.html