版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章用户自定义类型7.1结构体类型7.2结构体数组的使用7.3结构体指针变量的使用7.4用typedef声明新类型名7.5单向链表的建立与基本操作7.6联合体类型7.7枚举类型7.1结构体类型structure结构体:由不同类型的数据项组成的构造类型。
例如,在学生登记表中,每个学生的信息由学号、姓名、性别、成绩等数据项组成,各个数据项的类型可不一样。结构体类型:相当于文件系统中的记录。7.1结构体类型7.1.1定义结构体类型7.1.2定义结构体变量7.1.3结构体变量的使用7.1.4结构体变量的初始化7.1.1定义结构体类型声明结构体类型的形式:
struct
结构体名
{类型1成员名1;类型2成员名2;
….
类型n成员名n;
};{}括住的是成员列表7.1.1定义结构体类型例如:
structstu{intnum;charname[20];charsex;floatscore;};
定义一个结构类型structstu它由4个不同类型的成员组成:num,name,sex,score7.1.1定义结构体类型结构体类型一旦定义之后,就可作为一个类型名使用.结构体类型的使用格式为:struct
结构名例如
struct
stu
s1;注意:前面的struct不能省。7.1.1定义结构体类型嵌套的结构体类型:结构体类型中的成员,可以是一个结构体类型。structDate{
intyear;intmonth;intday;};structStudent{intnum;charname[20];charsex;structDate
birthdate;floatscore;};7.1.2定义结构体变量定义结构体变量有三种方法:1.先定义结构体类型,再声明结构体变量。structstu{intnum;charname[20];charsex;floatscore;};
structstu
boy1,boy2;图7-1结构变量boy1和boy2的内存分配sizeof(boy1)=sizeof(structstu)=29420147.1.2定义结构体变量定义结构体变量有三种方法:2.在定义结构体类型的同时,定义结构体变量。structstu{intnum;charname[20];charsex;floatscore;}boy1,boy2;
7.1.2定义结构体变量定义结构体变量有三种方法:3.不指定类型名而直接定义结构体变量。struct{intnum;charname[20];charsex;floatscore;}boy1,boy2;
7.1.3结构体变量的使用使用结构体变量成员的一般形式:结构体变量名.成员名例如:boy1.num,表示boy1的成员num;boy1.sex,表示boy1的成员sex。允许具有相同类型的结构体变量相互赋值。
结构体变量名1=结构体变量名2例如:boy2=boy1;把boy1的各成员的值挨个地赋给boy2中的各个成员。7.1.3结构体变量的使用除允许具有相同类型的结构体变量相互赋值以外赋值、输入、输出、运算等操作:针对结构体变量的成员例7-1结构体变量的声明,赋值,以及输入和输出操作。#include<stdio.h>voidmain(void){
structstu{
intnum;charname[20];charsex;floatscore;}boy1,boy2;
printf("Inputboy1:namenumsexscore\n"); scanf("%s%d%c%f",
,&boy1.num,&boy1.sex,&boy1.score);
boy2=boy1;
boy2.score=boy1.score+10;
printf("boy2:num=%d,name=%s,sex=%c,score=%f\n",
boy2.num,,boy2.sex,boy2.score);}7.1.3结构体变量的使用如果成员本身又是一个结构体变量,则必须逐级找到最低级的成员才能使用。structDate{
intyear;intmonth;intday;};structStudent{intnum;charname[20];charsex;structDate
birthdate;floatscore;};structStudents1;s1.birthday.month=6;7.1.3结构体变量的初始化在声明结构体变量的同时设置初值。例如:structstu{intnum;char*name;charsex;floatscore;}boy1,boy2={102,“Zhangping”,‘M’,78.5};
即:boy2.num=102,=“Zhangping”,boy2.sex=‘M’,boy2.score=结构体变量的初始化结构体变量声明之后,不能使用赋值语句给其整体赋值。例如:structstuboy2;
boy2={102,“Zhangping”,‘M’,78.5};
//错误赋值语句:boy2.num=102;=“Zhangping”;//对boy2.sex=‘M’,boy2.score=78.5
//对
boy2=boy1;//对7.1.3结构体变量的初始化嵌套的结构体变量的初始化:structStudent{intnum;charname[20];charsex;structDatebirthdate;floatscore;}s1={1,"Lihong",'M',{2012,5,30},78.5};即s1.birthdate.year=2012s1.birthdate.month=5s1.birthdate.day=307.2结构体数组的使用结构体数组:当数组的数据类型为结构体类型。结构体数组:用于表示具有相同结构的一个群体。如:某班的所有学生档案表某单位全体职工的工资表等7.2结构体数组的使用例如:structstuboys[5];7.2结构体数组的使用在声明数组时,对结构体数组作初始化例如:structstu{intnum;char*name;charsex;floatscore;}boy[2]={{10,"Liping",’F’,45},
{11,"Zhanghong",’M’,62.5}};{10,"Liping",’F’,45,11,"Zhanghong",’M’,62.5};替换7.2结构体数组的使用对数组的全部元素初始化赋值时,可不必给出数组的长度。例如:structstu{intnum;char*name;charsex;floatscore;}boy[]
={10,"Liping",’F’,45,11,"Zhanghong",’M’,62.5};
7.2结构体数组的使用例7-2设学生的信息包括:学号、姓名、性别、成绩。设计程序要求输入一组学生的信息,统计平均成绩,并按照成绩由低到高的顺序输出学生全部信息。#definelen3voidmain(void){ inti,j,k;structstu{intnum;charname[20];charsex;floatscore;}boy[len],temp; floatavg=0; //输入一组学生的记录,并统计平均成绩
for(i=0;i<len;i++){ printf("输入第%d条记录\n",i+1); printf("num?"); scanf("%d",&boy[i].num); printf("name?");
while(getchar()=='\n');
gets(boy[i].name);//输入姓名
下一个语句是输入字符串,则需要清除键盘缓冲区回车printf("sex?");scanf("%c",&boy[i].sex); //输入性别
printf("score?"); scanf("%f",&boy[i].score);//输入成绩
avg+=boy[i].score;//累加成绩到avg中
} avg/=len;//求平均成绩
for(i=0;i<len-1;i++){k=i;for(j=i+1;j<len;j++)if(boy[j].score>boy[k].score)k=j;temp=boy[k];boy[k]=boy[i];boy[i]=temp;}用选择法排序结构数组中的各元素
//输出排序的结构数组
printf("\n%5s%10s%3s%6s\n","num","name","sex","score");for(i=0;i<len;i++)
printf("%5d%10s%c%6.2f\n",boy[i].num,boy[i].name,boy[i].sex,boy[i].score); printf("averagescore:%.2f\n",avg);}7.3结构体指针变量的使用声明结构体指针变量的形式:struct结构名*
结构指针变量名
;例如:structstu
*pstu;
在定义stu结构的同时,声明指针变量。
structstu{…}*pstu;7.3结构体指针变量的使用结构体指针变量必须要先赋值后才能使用.结构体变量的首地址赋给指针变量。然后通过结构体指针变量访问结构体的各个成员成员访问的一般形式为:结构指针变量->成员名等同于(*结构指针变量).成员名7.3结构体指针变量的使用例如:structstu{intnum;char*name;charsex;floatscore;}*pstu,boy={102,"Zhangping",'M',78.5};pstu=&boy;pstu->num或(*pstu).num
等同于:boy.num注意:(*pstu)两侧的括号不可少,因为成员符“.”的优先级高于“*”。7.3结构体指针变量的使用
例如:
intc[5]={1,2,3};structst{inta;int*b;};structsts[]={10,&c[0],20,&c[3]},*p=s;printf(“%d\n",p->a);printf("%d\n",++(*(++p)->b));
输出结果:101102012300ps:abc++p例7-3结构体指针变量的应用。structstu{intnum;char*name;charsex;floatscore;}boy1={102,"Zhangping",'M',78.5},*pstu;main(){pstu=&boy1;printf("Number=%d\nName=%s\n",boy1.num,);printf("Sex=%c\nScore=%f\n\n",boy1.sex,boy1.score);printf("Number=%d\nName=%s\n",(*pstu).num,(*pstu).name);printf("Sex=%c\nScore=%f\n\n",*pstu).sex,(*pstu).score);printf("Number=%d\nName=%s\n",pstu->num,pstu->name);printf("Sex=%c\nScore=%f\n\n",pstu->sex,pstu->score);}例7-4结构体数据的动态内存分配。structstuboy1;结构体变量boy1的内存分配是静态分配的。结构体数据的内存分配也可为动态的#include<stdio.h>#include<stdlib.h>voidmain(){structstu{intnum;char*name;charsex;floatscore;}*p;
p=(structstu*)malloc(sizeof(structstu));//动态分配一个结构体数据的空间
p->num=300;//给结构体的各成员赋值
p->name="李红";p->sex='m';p->score=88.5;printf("Num=%d,Name=%s,Sex=%c,Score=%.1f\n",p->num,p->name,p->sex,p->score);free(p);//释放动态分配的结构体数据的空间}Num=300,Name=李红,Sex=m,core=88.5pnumnamesexscore李红7.4用typedef声明新类型名Typedef为已存在的数据类型定义一个新的类型名字(类型别名)。格式:typedef类型名称类型标识符;“类型名称”为已存在的数据类型名称“类型标识符”为新命名的类型名称。例如:typedefintINTEGER;typedefunsignedintCOUNT;
7.4用typedef声明新类型名新的类型名称定义之后,就可像基本数据类型使用。例如:typedefintINTEGER;typedefunsignedintCOUNT;
INTEGERi,j;COUNT
c;相当于inti,j;unsignedintc;7.4用typedef声明新类型名typedef的主要应用形式:(1)为基本数据类型定义新的类型名。(2)为自定义数据类型(结构体、公用体和枚举类型)定义一个简洁的类型名称。例如:typedefstruct{
intmonth;
intday;
intyear;}DATE;
DATEbirthday;
DATE*p;
7.4用typedef声明新类型名typedef的主要应用形式:(3)为数组定义一个简洁的类型名称。例如:typedefintNUM
[100];
NUMn;
n:定义了长度为100的整型数组变量
7.4用typedef声明新类型名typedef的主要应用形式:(4)为指针定义简洁的名称。例如:typedefchar*
STRING;STRINGcsName=“Jhon”;
7.4用typedef声明新类型名typedef的主要应用形式:5)为函数指针定义新的名称。例如:typedefint(*FUN)(inta,intb);FUN
f;
例7-5为函数指针定义新的类型名称的实例。#include<stdio.h>intMax(intx,inty){ returnx>y?x:y;}voidmain(){
typedefint(*FUN)(int,int);
FUN
pFun;//声明函数指针变量pFun
pFun=Max;//将函数Max赋给函数指针变量
printf("%d\n",pFun(2,3));//通过函数指针调用函数Max}7.5单向链表的建立与基本操作7.5.1什么叫链表?7.5.2如何定义结点的数据类型7.5.3创建动态链表7.5.1什么叫链表?链表:物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序通过链表中的指针链接次序实现的。链表由n个结点组成,结点可以动态生成。每个结点包括两个域:data:存储数据域next:存储后继结点地址的指针域。具有头指针的单向链表7.5.2如何定义结点的数据类型单向链表:如果链表中的每个结点中只有一个指向后继结点的指针,则该链表称为单链表。头结点:链表的第一个结点。尾结点:链表中的最后一个结点。尾结点的指针域为NULL(空指针)头指针:指向头结点的指针变量。通过头指针可以访问链表中的任何结点。具有头指针的单向链表7.5.2如何定义结点的数据类型单向链表的结点数据类型,可用结构体类型实现。格式为:structnode{
DATAdata;
structnode*next;};DATA可为基本类型或用户自定义的数据类型。7.5.2如何定义结点的数据类型例如:structnode{
intdata;
structnode*next;};7.5.2如何定义结点的数据类型例如:typedefstruct{intnum;char*name;charsex;floatscore;}Student;structnode{
Studentdata;
structnode*next;};typedefstructnode{
Studentdata;
structnode*next;}Node;
定义节点类型给结点类型structnode定义一个新的类型名Node;例7-6建立一个简单的单向链表。创建的含有3个结点a、b、c的单向链表,并用头指针head指向。定义一函数:printList(Node*head)完成:通过头指针输出单向链表中的所有结点信息。
1李华2张红3王国维^headnumname
Node#include<stdio.h>#include<string.h>typedefstructstu{intnum;charname[20];structstu*next;}Node;voidmain(){
Node*head,a,b,c;head=&a;a.num=1;strcpy(,"张红");a.next=&b;//a.next指向b结点生成a结点的内容head指向a结点
b.num=2;strcpy(,"李华");b.next=&c;//b.next指向c结点c.num=3;strcpy(,"王国维");c.next=NULL;//c.next指向空
printList(head);//打印整个链表}voidprintList(Node*head){ Node*p; p=head;
while(p!=NULL){ printf("Num=%d,Name=%s\n",p->num,p->name); p=p->next; }}生成b结点的内容生成c结点的内容通过头结点遍历整个链表中的所有结点并打印7.5.3创建动态链表动态链表:在程序运行时动态生成链表中的各结点(即结点的空间是动态内存分配的)。动态链表的创建:结点的定义:typedefstructstu{intnum;charname[20];structstu*next;}Node;numnamenextNodestu7.5.3创建动态链表设插入的结点放在链表的头部(即成为链表的新的头结点)。设单向链表有一个头指针head,初始状态为NULL,表示链表为空。headNULLnumname^headhead7.5.3创建动态链表1.插入一个结点到单向链表头部的过程:1)动态申请一结点空间,指针p指向该结点。即p=(Node*)malloc(sizeof(Node));2)给p指向的结点,赋予内容。即*p=s;3)判断链表为空(即head==NULL)时,则head=p;否则将p指向的结点加到链表头部。即:p.next=head;head=p;p^headhead7.5.3创建动态链表1.插入一个结点到单向链表头部的过程:1)动态申请一结点空间,指针p指向该结点。即p=(Node*)malloc(sizeof(Node));2)给p指向的结点,赋予内容。即*p=s;结构体变量赋值3)判断链表为空(即head==NULL)时,则head=p;否则将p指向的结点加到链表头部。即:p.next=head;head=p;phead7.5.3创建动态链表2通过循环,实现向链表插入n个结点。#include<stdio.h>#include<string.h>#include<stdlib.h>#definelen3typedefstructstu{intnum;charname[20];structstu*next;}Node;//插入一结点s到head指向的链表中,插到头Node*insert(Node*head,Nodes){ Node*p; p=(Node*)malloc(sizeof(Node)); if(p==NULL) exit(1); *p=s;
if(head==NULL) head=p; else{ p->next=head;//p.next指向旧头结点
head=p;//head指向新头结点
} returnhead;}结构体变量赋值相当于:p->num=s.num;strcpy(p->name,);p->next=s.next;//通过头指针head遍历整个链表voidprintList(Node*head){ Node*p; p=head; while(p!=NULL){
printf("Num=%d,Name=%s\n",p->num,p->name);
p=p->next; }}^headpvoidmain(){Node*head;inti;Nodes;head=NULL;//向链表插入len个结点
for(i=0;i<len;i++){ printf("输入第%d个学生Numname:",i+1);
scanf("%d%s",&(s.num),);
s.next=NULL; head=insert(head,s);}printList(head);}
7.6联合体类型联合体:能使多个变量共用同一块内存空间。联合体类型的定义、联合体变量的声明与使用,与前面讨论的结构体十分相似。7.6.1定义联合体类型联合体类型的声明一般形式:union
联合体名
{类型1成员名1;类型2成员名2;
…
类型n成员名n;
};7.6.1定义联合体类型例如:unionabc{inta;charb;doublec;}data;联合体中的a,b,c成员变量公用同一内存位置定义一个联合类型名abc,它含有三个成员:a,b,c。a从地址2000开始分配4个字节,b从地址2000开始分配1个字节,c从地址2000开始分配8个字节。联合体中的各成员变量公用同一内存位置,联合体变量data所占的内存长度等于最长的那个成员的空间长度这有别于结构体类型。7.6.2定义联合体变量联合体类型定义之后,可用于声明联合体变量。例如:定义了相同含义的联合体变量uVarunionabc
uVar;union{inta;charb;doublec;}uVar;unionabc{inta;charb;doublec;}uVar;7.6.3联合体变量的使用联合体变量的赋值,只能对成员变量进行。访问联合体变量成员的方法与结构体相同如:访问联合体成员变量的正确形式:uVar.auVar.buVar.cunionabc{inta;charb;doublec;}uVar;7.6.3联合体变量的使用注意:联合体变量可存放几种不同类型的成员,但任何时刻只能存放其中一个成员的值。联合体变量中起作用的成员是最后一次被赋值的成员对联合体变量的一个成员赋值后,原有变量的存储单元的值就被取代7.6.3联合体变量的使用例如:uVar.a=65;该语句执行后,uVar变量内存中存放的成员a的值65。uVar.b为多少?该语句执行后,uVar变量内存中存放的是成员b的值’A’,union{inta;charb;shortc;}uVar;65000000abc低字节高字节7.6.3联合体变量的使用定义联合体指针变量和联合体数组,与结构类似。例如:unionabcuVar,*p;p=&uVar;p->ap->bp->c7.6.3联合体变量的使用联合体作为在结构体的成员结构体作为联合体的成员例如:
struct{intage;char*addr;
union{inti;char*ch;}x;}y[5];访问y[2]中联合体x的成员i,可写成:
y[2].x.i;访问y[2]中联合体x的字符串指针ch的第一个字符可写成:
*(y[2].x.ch)
或*y[2].x.ch例7-8设有一个教师与学生通用的表格,教师信息有姓名、年龄、职业类别和教研室四项。学生信息有姓名、年龄、职业类别和班级四项。编程输入人员数据,并输出结果。解题思路:用一个结构体数组body[]来存放人员数据结构体共有4个成员:name、age、type和depadepa:联合体类型,这个联合体由两个成员组成:class:整型量office:字符数组。type:字符型:为’s’时表示depa存放的是班级class信息,否则存放的是教师的办公室地点。struct{ charname[10];intage;chartype;union{intclass;charoffice[10];}depa;}body[2];voidmain(){intn,i;for(i=0;i<2;i++){ printf("input:\nnameagetypedepartment\n");scanf("%s%d%c",
body[i].name,&body[i].age,&body[i].type);
if(body[i].type=='s')scanf("%d",&body[i].depa.class);elsescanf("%s",body[i].depa.office);}
printf("nameagetypeclass/office\n");for(i=0;i<2;i++){
if(body[i].type=='s')
printf("%s%3d%3c%d\n",
body[i].name,body[i].age,body[i].type,
body[i].depa.class);elseprintf("%s\t%3d%3c%s\n",
body[i].name,body[i].age,
body[i].type,body[i].depa.office);}}7.7枚举类型enum枚举类型是一个被命名的整型常量的集合。当一个变量只有几种可能的取值时,如表示星期或月份的变量,就可以定义为枚举类型。7.7枚举类型enum枚举类型的声明一般形式为:
enum
枚举名{
标识符1[=整型常数1],
标识符2[=整型常数2],...
标识符n[=整型常数n],
};标识符1、标识符2…标识符n:枚举元素或枚举常量。每一个枚举常量都代表一个整数。如果省掉“=整型常数i”时,则从第一个标识符开始,依次给标识符赋值为0,1,2,...但当枚举中的某个成员赋值后,其后的成员按依次加1的规则确定其值。7.7枚举类型例如:
enumWeekday{SUN,MON,TUE,WED,THU,FRI,SAT};
声明的枚举类型enumWeekday,其枚举元素SUN、MON、TUE、WED、THU、FRI、SAT的值分别为0、1、2、3、4、5、6。7.7
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 云南省文山壮族苗族自治州(2024年-2025年小学五年级语文)人教版期末考试(下学期)试卷及答案
- 工程制图教案创新:2024年的机遇与挑战
- 教育技术驱动:2024年《登上企鹅岛》课件的革新
- 《曾子杀猪》课件
- 新版2024年安全教育培训记录表设计与应用
- 2024年企业ERP采购流程重构培训
- 第47届世界技能大赛江苏省选拔赛网络系统管理项目技术文件V1.1
- 2024年XX企业社会责任与企业文化
- 2020盲盒经济洞察报告
- 《高科技智能住宅》课件
- 乐理知识考试题库130题(含答案)
- 人教版(2024)七年级地理上册2.2《地形图的判读》精美课件
- 2024年共青团入团积极分子团校结业考试试题库及答案
- 2024年辽宁高考历史试题(含答案和解析)
- 黄河商品交易市场介绍稿
- Unit 3 My friends Part C Story time(教学设计)-2024-2025学年人教PEP版英语四年级上册
- 2024中国海油校园招聘2024人(高频重点提升专题训练)共500题附带答案详解
- 孙中山诞辰纪念日主题班会主题班会
- 2024年安徽省合肥市中考语文题卷(含答案)
- G -B- 43630-2023 塔式和机架式服务器能效限定值及能效等级(正式版)
- 24春国开电大《工具书与文献检索》平时作业1-4答案
评论
0/150
提交评论