版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章构造数据类型语言程序设计第七章构造数据类型C7.1问题的提出7.2结构体数据类型7.3结构体数组7.4结构体指针7.5结构体变量与函数7.6共用体(联合体)数据类型7.7枚举数据类型7.8单向链表的概念
7.9位段
7.10本章小结7.11问与答内容简介7.1问题的提出语言程序设计第七章构造数据类型CC引入一种能集合不同数据类型于一体的数据类型:结构体类型。结构体变量可以拥有不同数据类型的成员,是不同数据类型成员的集合。让我们来观察一下住宿表、成绩表、通讯地址表等的结构.姓名(字符型)性别(字符型)年龄(整型)身份证号码(字符型)姓名(字符型)学号(字符型)班级(字符型)C语言(实型)高等数学(实型)姓名(字符型)家庭地址(字符型)邮编(长整型)电话(字符型)E-mail(字符型)对于以上种种表格,各成员的数据类型不尽相同,但各成员间又有密切的联系,所以用用户定义的结构体类型就能很好地解决这个问题。7.2结构体数据类型语言程序设计第七章构造数据类型C结构体是不同数据类型的数据所组成的集合体。与前面所讲的数组的区别在于其中的不同成员可以分别指定不同的数据类型。每一个结构体有一个名字,称为结构体名。所有成员都组织在该名字下。一个结构体由若干成员组成。它是组成结构体的要素,每个成员的数据类型可以不同,也可以相同。每个成员有自己的名字,称为结构体成员名。对结构体数据的操作是通过对结构体成员的引用实现的。结构体的应用为处理复杂的数据结构提供了有利的手段。7.2结构体数据类型语言程序设计第七章构造数据类型C由于结构体是由不同数据类型的数据组成的集合体,它包含若干成员,而这种结构在C语言中没有现成的数据类型。因此,在使用结构体进行数据处理时,应首先对结构体的组成进行描述。这种描述称为结构体定义。结构体定义实质上是在程序中构造一个结构体,声明结构体是由哪些成员组成以及这些成员的数据类型。结构体数据类型的定义形式为:struct
结构体名{结构体成员表列};struct是结构体类型指示符,是保留字。结构体名由标识符组成,称为结构体类型名,花括号内是该结构体中的各个成员,由它们组成一个结构体。7.2.1结构体数据类型的定义7.2结构体数据类型语言程序设计第七章构造数据类型C对结构体成员表列中的每个成员都应进行类型声明,结构体成员的表达形式:类型标识符结构体成员名;结构体名和结构体成员名的命名规则和变量名相同。例如对包含表7.1、7.2、7.3中全部类型数据的结构体类型的定义分别如下
:表7.1的结构体类型定义:structaccommodation{charName[20];/*姓名*/charSex;/*性别*/
intAge;/*年龄*/charNumber[18];/*身份证号码*/};7.2.1结构体数据类型的定义7.2结构体数据类型语言程序设计第七章构造数据类型C表7.2的结构体类型定义:structscore{charName[20];/*姓名*/charNumber[10];/*学号*/charClass[20];/*班级*/floatscore_C;/*C语言成绩*/floatscore_Math;/*高等数学成绩*/};7.2.1结构体数据类型的定义7.2结构体数据类型语言程序设计第七章构造数据类型C表7.3的结构体类型定义:structaddress{charName[20];/*姓名*/charHomeAddress[30];/*家庭地址*/longPostCode;/*邮编*/charTelephone[12];/*电话号码*/charEmail;/*E-mail*/};7.2.1结构体数据类型的定义7.2结构体数据类型语言程序设计第七章构造数据类型C注意:1、结构体类型定义只是描述了结构体的组织形式,在程序编译时并不为它分配存储空间。只是规定了一种特定的数据结构类型及它所占用的存储空间的存储模式。2、结构体成员可以是简单变量、数组、指针、结构体或共用体等。所以,结构体可以嵌套使用,即一个结构体变量也可以成为另一个结构体成员。3、结构体可以定义在函数内部,也可以在函数外部。在函数内部的结构体,只在函数内部可用;在函数外部定义的结构体,从定义点到源文件结束之间的所有函数都是可见的。一般是在源文件的开始部位对结构体进行定义。4、结构体成员名可以和程序中其它变量名相同,系统会自动识别它们,两者不会混淆。7.2.1结构体数据类型的定义7.2结构体数据类型语言程序设计第七章构造数据类型CC语言不仅提供了丰富的数据类型,如标准类型(int、float等)和用户自定义类型(数组、结构体、指针等),而且还允许用户在程序中使用typedef定义同义的数据类型,即允许用户为数据类型取“别名”。typedef类型定义的一般格式如下:typedef
类型新类型名;其中,类型是C语言提供的任一种数据类型,新类型名是代表这个类型的别名。例如,为int类型定义一个别名integer:
typedef
intinteger;此后,即可使用integer来定义整型变量。例如,下面的两个定义是等价的:
int
i,j;integeri,j;7.2.2关键字typedef的用法7.2结构体数据类型语言程序设计第七章构造数据类型C要注意的是,typedef类型定义只是定义了一个数据类型的别名,而不是定义一种新的数据类型,原来的数据类型仍然可用。利用typedef类型定义可为更复杂的类型定义别名。例如:
typedef
structstudent{
intnum;charname[20];charsex;
intage;floatscore;}STUDENT;为结构体类型structstudent定义一个别名STUDENT。此后,可以用它来定义结构体变量。7.2.2关键字typedef的用法7.2结构体数据类型语言程序设计第七章构造数据类型C此外利用typedef类型定义还可以定义数组类型或指针类型。例如,有如下定义:
typedefcharSTRING[10];/*定义STRING为字符数组类型*/STRINGstr;/*定义str
为字符数组变量*/
typedef
int*pointer;/*定义pointer为整型指针类型*/pointerp1,p2[5];/*定义p1为整型指针变量,p2
为整型指针数组*/
上述定义分别相当于如下定义:
charstr[10];
int*p1,p2[5];习惯上,常把typedef定义的类型别名用大写字母表示,以便与系统提供的标准类型标识符区分开。7.2.2关键字typedef的用法7.2结构体数据类型语言程序设计第七章构造数据类型C注意:1、使用typedef只是为已经存在的类型定义一个别名,并没有产生一个新的类型,原来的类型仍然可用。2、使用typedef类型定义可以定义各种类型别名,但不能定义变量。3、typedef与#define比较。例如:
typedef
intinteger;#defineintinteger两者的作用都是用integer代表int。但typedef是在编译时处理的,不是进行简单的字符替换,而是采用新的类型名定义变量。而#define是在预编译时处理的,只进行简单的字符串替换。7.2.2关键字typedef的用法7.2结构体数据类型语言程序设计第七章构造数据类型C4、通常把typedef定义的一些数据类型单独放在一个文件中,然后在需要它们的文件中用文件包含命令#include将它们包含进去,以提高程序的安全性。5、使用typedef类型定义有利于提高程序的可阅读性和可移植性。7.2.2关键字typedef的用法7.2结构体数据类型语言程序设计第七章构造数据类型C1、结构体变量的作用对结构体中数据(结构体成员)的操作是通过对结构体变量成员的引用来实现的。用结构体变量可以对结构体成员进行赋值、存取等运算。2、结构体变量定义的意义结构体变量同其它变量一样也必须先定义,后引用。结构体变量定义要按照结构体类型为被定义的结构体变量分配内存单元,而结构体类型定义不分配内存。7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C3、结构体变量定义的格式结构体变量定义一般采用如下三种格式:(1)在结构体类型定义的同时定义结构体变量定义格式如下:struct
结构体名{
结构体成员表列;}结构体变量名表;7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C例如:structstudent{longnum;charname[20];charsex;}student1,student2,student3;该例中结构体名为student,用它定义了三个结构体变量student1,student2,student3,三个变量具有相同的组成结构,即相同的类型。这种定义方法的特点是:定义一次结构体变量之后,在此之后的任何位置还可用该结构体类型(student)来定义其它的结构体变量。7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C(2)直接定义结构体变量,而不出现结构体名定义格式如下:struct{
结构体成员表列;}结构体变量名表;例如:struct{longnum;charname[20];charsex;}student1,student2,student3;这里定义的三个结构体变量与(1)相同,但这种定义方式不能用来再定义其它的结构体变量,要想定义新的结构体变量,必须将struct{}这部分重写
7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C(3)把结构体类型定义和结构体变量定义分开定义格式如下:struct
结构体名{
结构体成员表列;};……struct
结构体名结构体变量名表;7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C例如:structstudent{longnum;charname[20];charsex;};……structstudentstudent1,student2,student3;这种定义方法的特点是:可将对结构体类型的定义放在一个文件中(以.h为后缀的头文件)。若其它源文件需要用到此结构体类型,则可用#include命令将该文件包含到本文件中,便于使用。7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C注意:1、注意结构体类型定义和结构体变量定义的区别。结构体类型定义描述了结构体的类型,不分配内存,而结构体变量定义则是按照结构体类型定义中规定的结构体类型,在编译时,为结构体变量分配内存单元。该变量和其它变量一样可以进行赋值、存取或运算等操作,但结构体类型定义的数据类型是无法实现这些操作的。2、每个结构体变量表示的是一组成员(数据),而不是一个数据。3、在一个结构体中可以定义多少个结构体成员(结构体数据量的大小),不同版本的C语言规定不同,使用时应查阅相关资料。7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C注意:4、结构体变量的定义一定要在结构体类型定义之后或与结构体类型定义同时进行。没有定义的结构体类型,不能用它来定义结构体变量。5、结构体变量一般不用register(寄存器)型的存储方式。6、结构体变量中的成员可以单独使用,其作用和地位与一般变量相同。结构体变量占用实际内存的大小可用sizeof()运算来求得,即:sizeof(结构体名)。如求前面讲过的结构体structstudent占用内存的大小:sizeof(structstudent)结果等于61(TurboC环境下,VC6下是68)。即structstudent结构体的长度是61个字节。7.2.3结构体变量的定义7.2结构体数据类型语言程序设计第七章构造数据类型C和其它类型变量一样,对结构体变量的初始化,就是在定义结构体变量的同时,对其成员指定初值。结构体变量初始化的格式如下:struct
结构体名结构体变量名={初始数据};注意:1、只能对存储类型为extern(外部)型和static(静态)型结构体变量初始化,不能对存储类型为auto(自动)型的结构体变量初始化。2、初始化数据与数据之间用逗号隔开。3、初始化数据的个数要与初赋值的结构体成员的个数相等。7.2.4结构体变量的初始化7.2结构体数据类型语言程序设计第七章构造数据类型C和其它类型变量一样,对结构体变量的初始化,就是在定义结构体变量的同时,对其成员指定初值。结构体变量初始化的格式如下:struct
结构体名结构体变量名={初始数据};注意:1、只能对存储类型为extern(外部)型和static(静态)型结构体变量初始化,不能对存储类型为auto(自动)型的结构体变量初始化。2、初始化数据与数据之间用逗号隔开。3、初始化数据的个数要与初赋值的结构体成员的个数相等。4、初始化数据的类型要与相应的结构体成员的数据类型一致。7.2.4结构体变量的初始化7.2结构体数据类型语言程序设计第七章构造数据类型C5、不能直接在结构体成员表中对成员赋初值。例如:structstudent{longnum;charname[20];charsex;
intage;floatscore;charaddr[30];};sturctstudentstu1={101002,”Liming”,’M’,20,85.5,”AnHui
Ma’an
shan”};初始化正确。7.2.4结构体变量的初始化7.2结构体数据类型语言程序设计第七章构造数据类型C5、不能直接在结构体成员表中对成员赋初值。例如:structstudent{longnum=101002;charname[20]=”Liming”;charsex=’M’;
intage=20;floatscore=85.5;charaddr[30]=”AnHui
Ma’an
shan”;};则初始化错误。不能直接在结构体成员表中对成员赋初值。7.2.4结构体变量的初始化7.2结构体数据类型语言程序设计第七章构造数据类型C结构体变量成员的引用就是对结构体成员中所存放的数据进行读取操作。在对结构体成员进行引用时,只能对其成员进行直接操作,而不能对结构体变量整体进行操作。结构体变量成员引用有三种方式。(1)用结构体成员运算符方式“.”。用结构体成员运算符“.”引用结构体成员格式:结构体变量名.结构体变量成员名。(2)用指针方式定义一个指针(结构体指针),使它指向该结构体变量,这时就可以用指针和成员名来引用结构体变量成员了。其格式为:(*指针名).结构体变量成员名。7.2.5结构体变量成员的引用7.2结构体数据类型语言程序设计第七章构造数据类型C(3)用“—>”指向运算符引用结构体变量成员定义一个指针(结构体指针),使它指向该结构体变量,这时就可以用指针和成员名来引用结构体成员了。其格式为:指针名—>结构体变量成员名。本节先介绍第一种方式。后两种在7.4.1节中详细说明。例如:structstudent{longnum;charname[20];charsex;
intage;floatscore;charaddr[30];}stu1,stu2;7.2.5结构体变量成员的引用7.2结构体数据类型语言程序设计第七章构造数据类型C用结构体成员运算符“.”引用结构体成员。stu1.num=101002stu1.sex=’M’;stu1.age=20;stu1.score=85.5;strcpy(stu1.addr,”AnHui
Ma’an
shan”);结构体变量成员引用的几点说明如下:(1)结构体成员运算符“.”的优先级最高,结合性为左结合(自左至右)。例:stu1.num作为一个整体来看待,并对其操作。*stu1.num中“.”优先于“*”,其等价于*(stu1.num)。7.2.5结构体变量成员的引用7.2结构体数据类型语言程序设计第七章构造数据类型C(2)不能将一个结构体变量作为一个整体加以引用。例如将上例中stu1变量的内容输出,则printf(“%d,%s,%c,%d,%f,%s”,stu1);是错误的。只能分别对结构体变量中的各个成员进行输入输出。应改为:printf(“%d,%s,%c,%d,%f,%s”,stu1.num,stu1.sex,stu1.age,stu1.score,stu1.addr)。(3)对结构体成员的操作与其它变量一样,可进行各种运算。赋值运算:stu1.score=stu2.score;算术运算:average=(stu1.score+stu2.score)/2;自加、自减运算:stu1.age++;--stu2.age;关系运算:stu1.age>=stu2.age;7.2.5结构体变量成员的引用7.2结构体数据类型语言程序设计第七章构造数据类型C【例7-1】设计一个程序,输入一个学生的信息并显示。
#include“stdio.h”#include“string.h”#defineSTUDENTstructstudent
structstudent{intnum;charname[20];charsex;
intage;floatscore;};main(){charsex;STUDENTstu1;
printf(“inputstudent1’sinformation:\n”);7.2.5结构体变量成员的引用7.2结构体数据类型语言程序设计第七章构造数据类型C
printf(“numnameagesexscore\n”);scanf(“%d”,&stu1.num);/*输入学生学号*/scanf(“%s”,);/*输入学生姓名*/scanf(“%d”,&stu1.age);/*输入学生年龄*/sex=getchar();/*输入学生性别*/scanf(“%f”,&stu1.score);/*输入学生成绩*/stu1.sex=sex;printf(“num=%3d\nname=%s\nsex=%c\nage=%3d\nscore=%4.2f\n”,stu1.num,,stu1.sex,stu1.age,stu1.score);}Ex7_1.c演示7.2.5结构体变量成员的引用7.2结构体数据类型语言程序设计第七章构造数据类型C在进行结构体类型定义和结构体变量定义后,一般或者通过对结构体变量进行初始化,或者是通过对结构体变量成员进行赋值来完成对结构体变量成员的输入,下面通过一个例子来说明结构体变量成员的输入/输出的用法。7.2.6结构体变量成员的输入/输出【例7-2】设计程序,定义一个学生各科成绩结构体类型,并从键盘输入一组数据,计算出总分,并输出所有信息(学号、姓名、出生日期、数学、外语、计算机和总分)。#include“stdio.h”
structdate{intyear;
intmonth;
intday;};7.2结构体数据类型语言程序设计第七章构造数据类型Cstruct
scorelist{intnum;charname[10];
structdatebirthday;floatmath,english,computer,total;};main(){
struct
scoreliststu1;
printf(“\ninputnum:”);scanf(“%3d”,&stu1.num);
printf(“\ninputname:”);scanf(“%s”,);
printf(“\ninputbirthdayyearmonthday:”);7.2.6结构体变量成员的输入/输出7.2结构体数据类型语言程序设计第七章构造数据类型C
scanf(“%d%d%d”,&stu1.birthday.year,&stu1.birthday.month,&stu1.birthday.day);
printf(“\ninputmathenglishcomputer:”);scanf(“%f%f%f”,&stu1.math,&stu1.english,&puter);stu1.total=stu1.math+stu1.english+puter;printf(“num:%d,name:%s,birthday:%d%d%d,math:%.2f,\nenglish:%.2f,computer:%.2f,total:%.2f\n”,stu1.num,,stu1.birthday.year,stu1.birthday.month,stu1.birthday.day,stu1.math,stu1.english,puter,stu1.total);}Ex7_2.c演示7.2.6结构体变量成员的输入/输出7.3结构体数组语言程序设计第七章构造数据类型C定义一个结构体变量只能表示一个实体的相关信息,若要表示多个记录则要用结构体数组。结构体数组是结构体和数组的结合,数组内每个元素都是同一结构体类型的结构体变量,所以每个元素又都有若干个成员。结构体数组的定义和结构体变量的定义相同,如:structstudent{longnum;charname[20];charsex;
intage;floatscore;charaddr[30];}stu[4];7.3.1结构体数组的定义与初始化7.3结构体数组语言程序设计第七章构造数据类型C或是:structstudent{longnum;charname[20];charsex;
intage;floatscore;charaddr[30];};structstudentstu[4];这里,定义结构体数组stu有4个数组元素,分别从stu[0]到stu[3]。每个元素都是一个结构体变量,可用来表示4个学生的各项信息。7.3.1结构体数组的定义与初始化7.3结构体数组语言程序设计第七章构造数据类型C结构体数组的初始化和结构体变量的初始化类似,只不过在不同的数组元素之间用“{}”隔开,例如:structstudentstu[4]={{101001,”Wang”,’M’,22,88.2,”Beijing”},{101002,”Li”,’F’,20,85.2,”Nanjing”},{101003,”Zhang”,’M’,23,90.0,”Shandong”},{101004,”Zhao”,’F’,19,80.5,”Anhui”}};这里对四个结构体数组元素都进行了初始化,当然也可以只对前几个元素进行初始化,但是,在程序编译时编译器仍然会给没有初始化的元素分配内存空间。7.3.1结构体数组的定义与初始化7.3结构体数组语言程序设计第七章构造数据类型C【例7-3】输入一串字符,以“#”结束,统计其中a、b、c的个数并输出。#include"stdio.h"#include"string.h"structtimes{charc;
intcount;}abc[3]={{'a',0},{'b',0},{'c',0}};/*结构体数组初始化*/main(){int
i,j;charch;
scanf("%c",&ch);7.3.2结构体数组的应用程序范例Ex7_3.c演示7.3结构体数组语言程序设计第七章构造数据类型C
while(ch!='#')/*当前输入字符ch不等于#时循环*/{for(j=0;j<3;j++)
if(ch==abc[j].c)/*如果当前输入字符ch为数组中某个字符*/
abc[j].count++;/*数组中该字符对应的次数加1*/
scanf("%c",&ch);/*继续输入字符*/}
for(i=0;i<3;i++)printf("%c:%d\n",abc[i].c,abc[i].count);/*输出a、b、c出现次数*/}7.3.2结构体数组的应用程序范例7.4结构体指针语言程序设计第七章构造数据类型C指针的用途非常广泛,不仅可以指向普通的变量,也可以指向结构变量。结构体指针是一个用来指向结构体变量的指针变量,该指针变量的值就是结构体变量的起始地址;其目标变量是一个结构体变量,其目标是一个结构体变量的(一组)数据。7.4结构体指针语言程序设计第七章构造数据类型C结构体指针变量定义的一般形式:struct
结构体名*结构体指针名;例如:structstudent*op;/*op为指向结构体变量的指针*/注意:1、结构体名必须是已经定义过的结构体。2、结构体指针变量在使用前必须进行赋值操作,以把某个结构体变量的地址赋给结构体指针,使它指向该结构体变量。7.4.1结构体指针变量的定义与应用程序范例7.4结构体指针语言程序设计第七章构造数据类型C【例7-4】用三种方法引用结构体成员并输出。#include"stdio.h"structobject{charname[10];floathigh;floatweight;};main(){structobjecta={"first",1.73,74.2};
structobject*p=&a;7.4.1结构体指针变量的定义与应用程序范例
printf("%-10s%6.2f%6.2f\n",,a.high,a.weight);printf("%-10s%6.2f%6.2f\n",(*p).name,(*p).high,(*p).weight);printf("%-10s%6.2f%6.2f\n",p->name,p->high,p->weight);}Ex7_4.c演示7.4结构体指针语言程序设计第七章构造数据类型C从本例可以看出,访问结构体指针所指向的结构体变量的成员可以采用以下两种方法:方法(1):(*结构体指针名).成员项名例如:(*p).name,(*p).high,(*p).weight分别表示访问指针变量p指向的对象的name,high,weight等成员项。这里圆括号不能省略,它表示先访问指针指向的目标结构体变量,然后访问该结构体变量的成员项。如果省略,则上述表达式就变为如下形式:*结构体指针名.成员项名。从运算符的优先级看,“.”的优先级要高于“*”的,所以要先进行取成员运算,因为p是一个指针变量,不是结构体变量,所以无法进行取成员运算,以至于出现错误。7.4.1结构体指针变量的定义与应用程序范例7.4结构体指针语言程序设计第七章构造数据类型C方法(2):结构体指针名—>成员项名例如:p->name,p->high,p->weight就是利用了“—>”的形式访问结构体成员的。这种方法与前面给出的表示方法在功能上完全等价,但这种方法更为直观。这里的“—>”是一个运算符,称为指向运行符,其优先级与“.”相同。它表示访问指针指向的结构体变量中的成员。7.4.1结构体指针变量的定义与应用程序范例7.4结构体指针语言程序设计第七章构造数据类型C使用指针可使数组的操作更加高效灵活,并且上节也讲过了用指针处理结构体的情况,那么,指针来处理结构体数组,也可使程序更加高效和简洁。【例7-5】指向结构体数组的指针的应用。#include"stdio.h"structstudent{
intnum;charname[10];charsex;floatscore;}stu[5]={{1011,"Wang",'M',76},{1012,"Zhang",'M',87.5},{1013,"Liu",'F',90},{1014,"Zhou",'M',87},{1015,"Cheng",'F',88.5}};7.4.2结构体数组与指针变量及其应用程序范例Ex7_5.c演示7.4结构体指针语言程序设计第七章构造数据类型Cmain(){
structstudent*p;
printf("No.\tName\t\tSex\tScore\t\n");
for(p=stu;p<stu+5;p++)
printf("%d\t%s\t\t%c\t%.2f\n",p->num,p->name,p->sex,p->score);}7.4.2结构体数组与指针变量及其应用程序范例7.4结构体指针语言程序设计第七章构造数据类型C注意:p是指向结构体类型数据的指针变量,只能将数组的地址或某个数组元素的地址赋给p,不能将数据元素的成员或成员地址赋给p,否则,程序将会出错。例如:p=stu;/*正确*/p=&stu[0];/*正确*/p=stu[0].num;/*错误*/p=&stu[0].num;/*错误*/7.4.2结构体数组与指针变量及其应用程序范例7.5结构体变量与函数语言程序设计第七章构造数据类型C1、结构体类型变量的成员作函数参数既然结构体类型变量的成员可以在程序中直接引用,那么,在函数调用时,也可以将结构体类型变量各成员的值作为函数的实参进行数据传递。其用法和用普通变量作函数实参是一样的,属于“值传递”方式。例如:#include“stdio.h”structstudent{
intnum;charname[10];charsex;floatscore;};7.5.1结构体作为函数的形式参数与实际参数7.5结构体变量与函数语言程序设计第七章构造数据类型Cvoidf(floatx){…}main(){
structstudenta;
f(a.score);…}注意:在调用函数时,实参和形参的类型要一致。7.5.1结构体作为函数的形式参数与实际参数7.5结构体变量与函数语言程序设计第七章构造数据类型C2、结构体类型变量作函数参数C语言(ANSIC)允许使用结构体变量作实参进行数据传递,将主调函数中结构体变量所占用内存单元的内容全部顺序传递给形参。这是一种“值传递”方式,要求形参也必须是同类型的结构体变量。例如:
#include“stdio.h”
structstudent{
intnum;charname[10];charsex;floatscore;};7.5.1结构体作为函数的形式参数与实际参数7.5结构体变量与函数语言程序设计第七章构造数据类型C2、结构体类型变量作函数参数
viod
f(structstudentx){…}main(){…
f(a);…}7.5.1结构体作为函数的形式参数与实际参数7.5结构体变量与函数语言程序设计第七章构造数据类型C【例7-6】有一个结构体变量stu,内含学生学号、姓名和3门成绩。要求分别编写两个不同的函数输出学生的学号、姓名和3门成绩及总成绩。#include"stdio.h"#include"string.h"#defineFormat"%5d%9s%8.2f%8.2f%8.2f"structstudent{
intnum;charname[10];floatscore[3];};7.5.1结构体作为函数的形式参数与实际参数Ex7_6.c演示7.5结构体变量与函数语言程序设计第七章构造数据类型Cvoidpri1(structstudentst){
printf("numnamescore1score2score3sumscore\n");printf(Format,st.num,,st.score[0],st.score[1],st.score[2]);}voidpri2(floatx[]){floatsum;sum=x[0]+x[1]+x[2];printf("%8.2f\n",sum);}7.5.1结构体作为函数的形式参数与实际参数7.5结构体变量与函数语言程序设计第七章构造数据类型Cmain(){
structstudentstu={1011,"Liming",76.5,89.5,81};pri1(stu);pri2(stu.score);}7.5.1结构体作为函数的形式参数与实际参数7.5结构体变量与函数语言程序设计第七章构造数据类型CC语言中,允许结构体变量作为函数的返回值。此时,在函数定义时需要说明函数返回值的类型为相应结构体类型。【例7-7】在函数input()中输入一个学生信息并返回,在函数list()中显示其信息。#include"stdio.h"structstudent{
intnum;charname[10];
intage;charsex;
intclass;};7.5.2函数的返回值类型为结构体Ex7_7.c演示7.5结构体变量与函数语言程序设计第七章构造数据类型Cstructstudentinput(){
structstudentstu;scanf("%d\t%s\t%d\t%c\t%d",&stu.num,,&stu.age,&stu.sex,&stu.class);
return(stu);}voidlist(structstudentstu){
printf("\n
num:%d\tname:%s\tage:%d\tsex:%c\tclass:%d\n",stu.num,,
stu.age,stu.sex,stu.class);}7.5.2函数的返回值类型为结构体7.5结构体变量与函数语言程序设计第七章构造数据类型Cmain(){
structstudentstu;
printf("\nnumnameagesexclass\n");
stu=input();
printf("\nStudentinformation:\n");
list(stu);}7.5.2函数的返回值类型为结构体7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C共用体和结构体类似,也是一种构造类型,它将不同类型的数据项存放在同一内存区域内,组成共用体的各个数据项也称为成员或域,共用体有时也称为联合体。共用体与结构体不同的是:结构体变量的各成员占用连续的不同的存储单元,而共用体变量的各成员占用相同的存储单元。由于共用体类型将不同类型的数据在不同时刻存储到同一内存区域内,因此使用共用体类型可以更好地利用存储空间。7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C共用体类型定义的一般格式如下:
union共用体名
{
成员列表
};其中,union为关键字,表示定义一个共用体类型;共用体名为C语言合法的标识符;花括号内的成员列表用来说明组成该共用体的各个成员,对每个成员应进行类型说明,其说明格式为:类型符成员名;成员名的命名应符合C语言标识符的命名规则。7.6.1共用体(联合体)数据类型的定义7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C例如:
uniondata{charname[10];
intage;floatscore;};上述定义中,uniondata是一个共用体类型,与结构体类型相似,共用体类型在使用过程中和系统提供的标准类型具有同样的地位和作用。一个共用体类型包含若干个成员,每个成员的类型可以不一样。共用体类型数据的所有成员共同占用同一段存储空间,在存储时所占的内存单元字节数等于其中最长的成员所占内存单元字节数。7.6.1共用体(联合体)数据类型的定义7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C共用体类型变量的定义与结构体类型变量的定义相似,通常采取以下三种形式:1、先定义共用体类型,再定义共用体类型变量定义形式为:共用体类型名共用体变量名;例如:
uniondata{charname[10];charsex;
intage;floatscore;};/*定义uniondata共用体类型*/uniondatastu1,stu2;7.6.2共用体(联合体)类型变量的定义与引用7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C2、在定义共用体类型的同时定义变量,定义形式为:union共用体名{类型名1成员名1;类型名2成员名2;
…
类型名n成员名n;}变量名列表;例如:uniondata{charname[10];charsex;
intage;floatscore;}stu1,stu2;/*定义stu1,stu2为uniondata类型变量*/7.6.2共用体(联合体)类型变量的定义与引用7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C3、直接定义共用体类型变量,定义形式为:union{类型1成员名1;类型2成员名2;
…
类型n成员名n;}变量名列表;例如:union{charname[10];charsex;
intage;floatscore;}stu1,stu2;/*定义stu1,stu2为uniondata类型变量*/7.6.2共用体(联合体)类型变量的定义与引用7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C同结构体类型变量一样,在C语言程序中只能引用共用体类型变量的成员,不能直接引用共用体变量。引用共用体变量成员一般形式如下:变量名.成员名例如:stu1.age=31;注意:1、共用体是在同一个内存段中存放几种不同类型的成员,但在某一个具体的瞬间,只能存放其中的一个成员,即某一瞬间只有一个成员起作用,不是所有的成员都同时起作用。7.6.2共用体(联合体)类型变量的定义与引用7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C2、共用体变量中起作用的成员是最后一次存放的成员,前面存放的成员被后面存放的成员所覆盖。例如:
union{charname[10];
intage;floatscore;}stu1,stu2;…stu1.age=28;stu1.score=90.5;执行完这两条语句后,只有stu1.score成员有效,stu1.age成员内容已经被stu1.score成员覆盖了。7.6.2共用体(联合体)类型变量的定义与引用7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C3、共用体变量的地址与其各成员的地址是相同的。即&stu1、&stu1.age、&stu1.score和&都是同一个值。4、不能直接对共用体变量赋值,也不能直接引用共用体变量,更不能对共用体变量进行初始化。5、共用体变量不能作为函数的参数,函数的返回值不能为共用体变量。6、共用体类型可以用于结构体类型定义中,也可以定义共用体类型数组。结构体类型也可以出现在共用体类型定义中,另外,数组可以作为共用体成员。7、可以使用指向共用体变量的指针变量。7.6.2共用体(联合体)类型变量的定义与引用7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C【例7-8】一个简单的学校人员管理程序。输入一组人员信息,包含姓名、性别、年龄、身份(如果是学生,包含学号,如果是教师,包含职称)。#include"stdio.h"unionvocation{longgrades;chartitles[10];};structperson{charname[10];charsex;
intage;charjudge;unionvocationpp;};7.6.2共用体(联合体)类型变量的定义与引用Ex7_8.c演示7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型Cmain(){structpersonst[4];
inti;
for(i=0;i<4;i++){printf("Inputnamesexagejudge(S/T):\n");
scanf("%s%c%d%c",&st[i].name,&st[i].sex,&st[i].age,&st[i].judge);
if(st[i].judge=='S'){printf("grades:");
scanf("%ld",&st[i].pp.grades);}
if(st[i].judge=='T'){printf("tltles:");
scanf("%s",st[i].pp.titles);}}7.6.2共用体(联合体)类型变量的定义与引用7.6共用体(联合体)数据类型语言程序设计第七章构造数据类型C
printf("\n");
for(i=0;i<4;i++){
if(st[i].judge=='S')
printf("%s%c%d%c%ld\n",st[i].name,st[i].sex,st[i].age,st[i].judge,
st[i].pp.grades);
if(st[i].judge=='T')
printf("%s%c%d%c%s\n",st[i].name,st[i].sex,st[i].age,st[i].judge,
st[i].pp.titles);}}7.6.2共用体(联合体)类型变量的定义与引用7.7枚举数据类型语言程序设计第七章构造数据类型C枚举类型也是一种数据类型。把变量的值一一列举出来,以后只可能取所列举出来的有限的几种值,可以把它定义为枚举类型数据。枚举类型定义的一般形式为:enum
枚举名{枚举值列表};其中,enum为关键字,表示定义一个枚举类型;枚举类型名为C语言规定的合法的标识符;花括号内的标识符称为枚举元素或枚举常量。各枚举常量之间用逗号隔开。例如,定义一个枚举类型代表一周的七天:enum
week{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};这里定义了一个枚举类型,名为week,包括7个枚举常量,即一周中的七天。7.7.1枚举数据类型的定义7.7枚举数据类型语言程序设计第七章构造数据类型C需要注意的是,每个枚举常量对应一个整数值。一般情况下,一个枚举类型中各枚举常量从0开始顺序取值。在上面的例子中,Sunday到Saturday分别取值为0、1、2、3、4、5、6。另外,在定义枚举类型时,也可以显式指定各枚举常量的值。例如:enum
week{Sunday=7,Monday=1,Tuesday,Wednesday,Thursday,Friday,Saturday};此时,Monday值为1,其后的枚举常量取值顺序增1,即Tuesday到Saturday的值分别为2~6。又如:enum
color{red=0,yellow,blue=3,white,black};此时,red=0,red之后的yellow顺序增1,即yellow=1,blue=3,其后white和black分别为4和5。7.7.1枚举数据类型的定义7.7枚举数据类型语言程序设计第七章构造数据类型C定义枚举变量可以仿照结构体变量定义方法,先定义枚举类型,再定义枚举变量,定义枚举变量也有3种方式:(1)先定义枚举类型再定义枚举类型变量。例如:enum
week{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};enumweekworkday;(2)在定义枚举类型的同时定义枚举类型变量。例如:enum
week{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday}weekday;(3)直接定义枚举类型变量。例如:Enum{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday}weekday;7.7.2枚举类型变量的定义与引用7.7枚举数据类型语言程序设计第七章构造数据类型C注意:1、在枚举类型定义中,枚举常量的命名规则与标识符相同,并且不能另做他用。2、枚举常量不是变量,不能在程序中用赋值语句对其赋值。3、只能把枚举常量赋给枚举变量,不能把枚举常量对应的整数值直接赋给枚举变量。例如,下面的两个语句中,第一个是合法的,而第二个是不合法的。
enumweekworkday;workday=Saturday;workday=6;如果将第二个赋值语句改写成如下形式,是合法的:workday=(enumdays)6;这里,是把整数6强制转换为enumdays类型后赋给变量workday。7.7.2枚举类型变量的定义与引用7.7枚举数据类型语言程序设计第七章构造数据类型C注意:4、枚举常量不是字符常量,也不是字符串常量,使用时不能加单引号或双引号。例如,下面的赋值语句是不合法的:workday=”Monday”;5、输出枚举常量或枚举变量的整数值时,应使用整型输出格式符,若要输出枚举常量名,则需要经过转换。例如:workday=Monday;if(workday==Monday)printf(“Monday”);6、枚举常量可进行比较运算,由它们对应的整数参加比较。7.7.2枚举类型变量的定义与引用7.7枚举数据类型语言程序设计第七章构造数据类型C【例7-9】从键盘上输入一个1~7之间的整数,显示与之对应的枚举常量名。#include"stdio.h"main(){
enum
days{Monday=1,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};/*定义与星期对应的枚举类型*/
enumdaysworkday;
inti;
printf("inputi:");
scanf("%d",&i);workday=(enum
days)i;7.7.2枚举类型变量的定义与引用Ex7_9.c演示7.7枚举数据类型语言程序设计第七章构造数据类型C
switch(workday)/*判断workday对应的枚举常量并输出*/{caseMonday:
printf("\nMonday\n");break;caseTuesday:
printf("\nTuesday\n");break;caseWednesday:
printf("\nWednesday\n");break;caseThursday:
printf("\nThursday\n");break;caseFriday:
printf("\nFriday\n");break;
7.7.2枚举类型变量的定义与引用7.7枚举数据类型语言程序设计第七章构造数据类型CcaseSaturday:
printf("\nSaturday\n");break;caseSunday:
printf("\nSunday\n");break;default:
printf("\ninput
error!pleaseinputintegerfrom1to7\n");}}7.7.2枚举类型变量的定义与引用7.8单向链表的概念语言程序设计第七章构造数据类型C链表是一种常见的数据结构。它的特点是用一组任意的存储单元存储数据。这些存储单元可以是连续的,也可以是不连续的,使得计算机内存和空间能够被高效地利用。链表中的存储单元,可以在程序执行过程中动态建立、插入和删除。这完全克服了用数组实现存储的一些缺陷:预先分配最大空间导致不能充分利用空间;在插入删除和交换数据时,需要移动大量数据,增加了程序运行时间;表的内容难以扩充。链表是由称为结点的元素组成的,结点的多少根据需要而定。每个结点都应包括两部分内容:一是数据部分,该部分可以根据需要定义一个由多个成员组成的结构体类型,用于存放需要处理的数据;二是指针部分,该部分存放的是下一个结点的地址,链表中的每个结点通过指针链接在一起,图7.9(a)和(b)分别是一个空链表和有四个结点的链表。7.8.1问题的提出7.8单向链表的概念语言程序设计第七章构造数据类型C头指针结点数据域指针域hNull(a)空链表(b)非空链表h图7.9单链表示意图7.8.1问题的提出7.8单向链表的概念语言程序设计第七章构造数据类型C最简单的单链表(SingleLinkedList)中每个结点只有一个数据域(或称分量)和一个指针域,图7.9就是一个最简单的单链表示意图。用C语言描述单链表如下:structnode{intdata;/*可以根据需要定义数据域的个数及类型*/
structnode*next;};structnode*head,*p;上述定义中,变量head和p都是类型为structnode的指针变量。通常,p所指的结点即结构体,只有声明,并未定义。而在程序执行过程中,当需要时才动态产生,即所谓的动态链表。建立单链表是在程序执行过程中从无到有地建立起一个链表,即一个一个的开辟结点和输入各结点数据,并建立起前后相连的关系。7.8.2单向链表的建立7.8单向链表的概念语言程序设计第七章构造数据类型C【例7-10】一个简单链表的建立和输出。#include"stdio.h"structnode/*定义结构体变量*/{
intdata;/*数据域*/
structnode*next;/*指针域*/};main(){structnodea,b,c;/*定义3个结点变量a,b,c*/
structnode*head,*p;/*定义两个指向结点的指针变量*/
a.data=100;/*为结点的数据域赋值*/
b.data=200;
c.data=300;7.8.2单向链表的建立Ex7_10.c演示7.8单向链表的概念语言程序设计第七章构造数据类型Chead=&a;/*头指针head指向结点a*/
a.next=&b;/*a的指针指向结点b*/
b.next=&c;/*b的指针域指向结点c*/
c.next=NULL;/*c的指针域置空*/p=head;/*使p指向表头*/
while(p!=NULL)/*循环输出链表内容*/{printf("%5d",p->data);/*输出p指向的结点的数据域*/p=p->next;/*使p指向下一个结点*/}}100head200300abc
例7-10建立的链表∧7.8.2单向链
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 福州理工学院《康复功能评定学》2025-2026学年期末试卷
- 安徽中澳科技职业学院《普通教育学》2025-2026学年期末试卷
- 安徽邮电职业技术学院《世界经济概论》2025-2026学年期末试卷
- 合肥共达职业技术学院《服务管理》2025-2026学年期末试卷
- 财务员职业发展进阶规划
- 专业选择就业分析
- 焊丝镀铜工安全教育强化考核试卷含答案
- 水族造景工岗前进阶考核试卷含答案
- 织袜工变更管理水平考核试卷含答案
- 商店商品出入库管理制度
- (甘肃二模)甘肃省2026年高三年级第二次模拟考试生物试卷(含答案)
- 2024年广东省深圳市中考语文试题(原卷版)
- 2026届江苏省南京市、盐城市高三一模英语卷(含答案)
- 2026年数据资产合规性评估报告范本
- 统编版(新版)道德与法治八年级下册课件13.1全面依法治国的指导思想
- 2026年南阳农业职业学院单招职业适应性考试题库及答案详解(真题汇编)
- 2025年三季度云南航空产业投资集团招聘(云南云航投现代物流有限公司岗位)考试笔试历年常考点试题专练附带答案详解2套试卷
- 公路工程项目首件工程认可制监理实施细则
- 3.长方体和正方体(单元测试)2025-2026学年五年级数学下册人教版(含答案)
- 八大特殊作业安全管理流程图(可编辑)
- 石灰石矿山破碎系统施工方案
评论
0/150
提交评论