C-C++语言程序设计基础-第9章-课件1_第1页
C-C++语言程序设计基础-第9章-课件1_第2页
C-C++语言程序设计基础-第9章-课件1_第3页
C-C++语言程序设计基础-第9章-课件1_第4页
C-C++语言程序设计基础-第9章-课件1_第5页
已阅读5页,还剩70页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9章构造数据类型9.1结构体9.2共用体9.3枚举9.4自定义数据类型9.1结构体9.1.1结构体的定义 9.1.2结构体变量说明 9.1.3结构体变量的引用9.1.4结构体数组 9.1.5结构体与函数9.1.6指向结构体变量的指针 9.1.7动态存储分配 9.1.8结构体与链表 9.1结构体概述

在前面章节所见到的程序中,大多数的数据都是独立的,没有内在联系的 。比如:int

a,b;floatc,d;charname[20];但在实际生活和工作中,很多不同类型的数据是存在内在联系的。比如学生基本信息。学号num姓名name性别sex年龄age成绩score家庭住址addr1001LiXiaoM1989.0hunan1002JinF1890.0beijing1003FengF1960.5guangxi1004RongM1874.5qinghai提问:输出分数最高的学生的成绩?main(){inti,num,age;floatscore;charsex,name[20],addr[30];intmax=0;for(i=1;i<=4;i++){scanf(“%d%d%f”,&num,&age,&score);scanf(“%c”,&sex);gets(name);gets(addr);if(max<score)max=score;}printf(“%f\n”,max);}缺点:1.变量过多,同一学生的各个数据无联系,没有整体概念,不便管理;2.操作不便(如更新数据)很明显,我们需要一种能把一个学生的各种信息构成一个整体的构造性数据结构。

但目前学过的数组、指针都不合适。使用结构体类型可以处理组合数据结构体类型

“结构体”是一种构造类型,它是由若干“成员”组成的。每一个成员可以是基本数据类型或者构造类型。struct

[结构体名]{

类型标识符成员名;类型标识符成员名;

…………….};成员类型可以是基本型或构造型struct是关键字,不能省略合法标识符可省:无名结构体一、结构的定义

structstudent{ intnum;charname[20];charsex;intage;floatscore;charaddr[30]; };学号num姓名name性别sex年龄age成绩score家庭住址addr1001LiXiaoM1989.0hunan1002JinF1890.0beijing1003FengF1960.5guangxi1004RongM1874.5qinghaistructstudent为构造的结构体9.1.2结构体变量说明例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};

structstudentstu1,stu2;

1.先定义结构体类型,再定义结构体变量一般形式:struct结构体名{

类型标识符成员名;类型标识符成员名;

…………….};struct结构体名变量名表列;stu1,stu2为结构体变量2.定义结构体类型的同时定义结构体变量一般形式:struct结构体名{

类型标识符成员名;类型标识符成员名;

…………….}变量名表列;例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;3.直接定义结构体变量一般形式:struct{

类型标识符成员名;类型标识符成员名;

…………….}变量名表列;例struct{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;

用无名结构体直接定义变量只能一次例:结构体变量存储。

structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};

structstudentstu1;

structstudent结构体类型定义描述结构的组织形式,不分配内存;结构体变量stu1分配内存,占63个字节namenumsexscoreaddr4字节4字节20字节1字节4字节30字节……..age4.结构体可嵌套。比如下列数据:学号num姓名name出生年月日birthday1001LiXiao1989.12.11002Jin1989.11.121003Feng1989.2.11004Rong1990.5.7用什么类型表示合适?structdate{intmonth;intday;intyear;};structstudent{intnum;charname[20];

structdatebirthday;}stu;numnamebirthdaymonthdayyearstructstudent{intnum;charname[20];

structdate{intmonth;intday;intyear;}birthday;}stu;numnamebirthdaymonthdayyear结构体课堂练习1:1.当定义一个结构变量时,系统分配给它的内存是

)。A.各成员所需内存量的总和

B.结构中第一个成员所需内存量C.成员中占内存量最大的容量

D.结构中最后一个成员所需内存量2.已知:struct{intk;charc;floata;}test;则sizeof(test)的值是(

)。A.6 B.7 C.8 D.9DA3.如下说明语句,则下面叙述不正确的是(

)。structstu{inta;floatb;}stutype;A)struct是结构类型的关键字B)structstu是用户定义的结构类型C)stutype是用户定义的结构类型名D)a和b都是结构成员名C成员(分量)运算符优先级:1结合性:从左向右引用方式:

结构体变量名.成员名例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;

stu1.num=10;stu1.sex=‘M’;stu1.score+=stu2.score;stu1.age++;9.1.3结构体变量的引用引用规则结构体变量不能整体引用,只能引用变量成员可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用例structstudent{intnum;charname[20];

structdate{intmonth;intday;intyear;}birthday;}stu1,stu2;stu1.birthday.year=2010stu1=stu2;9.1.3结构体变量的引用引用规则4.已知学生记录描述为:structstudent{intno;charname[20];charsex;struct{intyear;intmonth;intday;}birth;}s;设结构变量s中的“birth”应是“1985年10月1日”,则下面正确的赋值方式是(

)。A)year=1985B)birth.year=1985month=10birth.month=10day=1birth.day=1C)s.year=1985D)s.birth.year=1985s.month=10s.birth.month=10s.day=1s.birth.day=1D学号num姓名name性别sex年龄age成绩score家庭住址addr1001LiXiaoM1989.0hunan1002JinF1890.0beijing1003FengF1960.5guangxi1004RongM1874.5qinghai结构体例1:输出下面数据中分数最高的学生姓名与分数?第一步:如何输入每个学生的信息?方式二:初始化方式一:赋值structstu{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;main(

){stu1.num=1001;strcpy(,"LiXiao");scanf("%c%d%f",&stu1.sex,&stu1.age,&stut1.score);strcpy(stu1.addr,"hunan");}方式一、结构体变量的赋值

structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};structstudentstu1={1001,"LiXiao",‘M’,19,89.0,“hunan”};structstudent{intnum;charname[20];charsex;intage;floatscore;

charaddr[30];}stu1={1001,"LiXiao",‘M’,19,89.0,“hunan”};方式二、初始化学号num姓名name性别sex年龄age成绩score家庭住址addr1001LiXiaoM1989.0hunan1002JinF1890.0beijing1003FengF1960.5guangxi1004RongM1874.5qinghai结构体例1:输出下面数据中分数最高的学生姓名与分数?程序如下:#include<stdio.h>#include<string.h>structstu{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1={1001,"LiXiao",'M',19,89.00,"hunan"},stu2={1002,"Jin",'F',18,90.00,"beijing"},stu3={1003,"Feng",'F',19,60.50,"guangxi"},stu4={1004,"Rong",'M',18,74.50,"qinghai"};初始化数据main(){floatmaxscore=0;charmaxname[30];if(maxscore<stu1.score){maxscore=stu1.score;strcpy(maxname,);}if(maxscore<stu2.score){maxscore=stu2.score;strcpy(maxname,);}if(maxscore<stu3.score){maxscore=stu3.score;strcpy(maxname,);}if(maxscore<stu4.score){maxscore=stu4.score;strcpy(maxname,);}printf("姓名:%s最高分:%f\n",maxname,maxscore);}

每个学生信息虽然包含不同类型数据,但每个学生的属性都是一样的。可以用数组表示。

9.1.4结构体数组结构体数组的定义三种形式:形式一:

structstudent{intnum;charname[20];charsex;intage;};structstudentstu[2];形式二:structstudent{intnum;charname[20];charsex;intage;}stu[2];形式三:struct{intnum;charname[20];charsex;intage;}stu[2];numnamesexagenumnamesexagestu[0]stu[1]25B结构体数组初始化顺序初始化:structstudent{intnum;charname[20];charsex;intage;};structstudentstu[]={100,“WangLin”,‘M’,20,101,“LiGang”,‘M’,19,110,“LiuYan”,‘F’,19};分行初始化:structstudent{intnum;charname[20];charsex;intage;};structstudentstu[]={{100,“WangLin”,‘M’,20},{101,“LiGang”,‘M’,19},{110,“LiuYan”,‘F’,19}};全部初始化时维数可省结构体数组引用引用方式:结构体数组名[下标].成员名stu[0].numstu[1].name学号num姓名name性别sex年龄age成绩score家庭住址addr1001LiXiaoM1989.0hunan1002JinF1890.0beijing1003FengF1960.5guangxi1004RongM1874.5qinghai结构体例1:输出下面数据中分数最高的学生姓名与分数?程序修改如下:#include<stdio.h>#include<string.h>structstu{intnum;charname[20];charsex;intage;floatscore; charaddr[30];}stu[4]={{1001,"LiXiao",'M',19,89.00,"hunan"},{1002,"Jin",'F',18,98.00,"beijing"},{1003,"Feng",'F',19,60.50,"guangxi"},{1004,"Rong",'M',18,74.50,"qinghai"}};数组初始化main(){floatmaxscore=0;charmaxname[30];inti;for(i=0;i<4;i++)if(maxscore<stu[i].score){maxscore=stu[i].score;strcpy(maxname,stu[i].name);}printf("姓名:%s最高分:%f\n",maxname,maxscore);}姓名name选票countLi0Zhang0Wang0结构体例2:10人投票,请统计3个候选人的选票情况。程序如下:#include<stdio.h>#include<string.h>structperson{charname[20];intcount;}leader[3]={"li",0,"zhang",0,"wang",0};数组初始化voidmain(){ inti,j;charleader_name[20]; for(i=1;i<=10;i++) {scanf("%s",leader_name);//投票人所投的候选人的姓 for(j=0;j<3;j++) if(strcmp(leader_name,leader[j].name)==0) leader[j].count++; } printf("\n"); for(i=0;i<3;i++) printf("%5s:%d\n",leader[i].name,leader[i].count);}结构体课堂练习2:1.有如下定义:structperson{charname[9];intage;};structpersonclass[10]={"Johu",17,"Paul",19,"Mary",18,"Adam",16};根据上述定义,能输出字母M的语句是(

)。A、printf("%c\n",class[3].name);B、printf("%c\n",class[3].name[1]);C、printf("%c\n",class[2].name[1]);D、printf("%c\n",class[2].name[0]);D2.下面程序的运行结果是()。#include"stdio.h"main(){structcmplx{intx;inty;}cnum[2]={1,3,2,7};printf("%d\n",cnum[0].y/cnum[0].xcnum[1].x);}A.0 B.1 C.3 D.6D9.1.5结构体与函数

1.结构体变量作为函数的参数

结构体变量作为函数参数时,形参与实参的结构体变量类型应当完全一致,函数调用时直接将实参结构体变量的各个成员的值全部传递给形参结构体变量。【例9.7】用函数实现数组元素输出。#include"stdio.h”structstu{intnum;charname[20];charsex;floatscore;}student[5]={{1001,"LiXiao",'M',89.00},{1002,"Jin",'F

',90.00},{1003,"Feng",'F

',60.50},{1004,"Rong",'M

',74.50},{1005,"ZhuJi",'F

',55.00}};voidprint(structstus) //定义print函数{printf("%d%s%c%f\n",s.num,,s.sex,s.score);}voidmain(){inti;for(i=0;i<5;i++)print(student[i]); //调用print函数输出结构体变量}9.1.6指向结构体变量的指针指向结构体变量的指针定义形式:struct结构体名*结构体指针名;例structstudent*p;使用结构体指针变量引用成员形式存放结构体变量在内存的起始地址numnamesexagestupstructstudent{intnum;charname[20];charsex;intage;}stu;structstudent*p=&stu;(*结构体指针名).成员名结构体指针名->成员名结构体变量名.成员名指向运算符优先级:1结合方向:从左向右例指向结构体的指针变量例intn;int*p=&n;

*p=10;n=10#include<stdio.h>structstu{ intnum; charname[20]; charsex; floatscore; }student1={1001,"LiXiao",'M',89.00},*pstu;voidmain(

){pstu=&student1;

printf(“%d\n%s\n",(*pstu).num,(*pstu).name);printf(“%c\n%.2f\n\n",(*pstu).sex,(*pstu).score);

printf(“%d\n%s\n",pstu->num,pstu->name);printf(“%c\n%.2f\n\n",pstu->sex,pstu->score);}

structstu{ intnum; charname[20]; charsex; floatscore; }stu1,stu2,*pstu1=&stu1;structstu*pstu2;

pstu2=&stu2;//指针变量pstu2指向stu2

stu1.num=101;(*pstu1).num=101结构体课堂练习3:1.有定义如下:structsk{inta;floatb;}data,*p;如果p=&data;则对于结构变量data的成员a的正确引用是(

)。A.(*).data.a B.(*p).a C.p->data.a D.p.data.aB2.已知:structst{intn;structstnext;};staticstructsta[3]={1,&a[1],3,&a[2],5,&a[0]},p;如果下述语句的显示是4,则对指针p的赋值是()。printf(“%d”,++(p->next->n);A.p=&a[0]; B.p=&a[1]; C.p=&a[2]; D.p=&a[3];A3.若有以下定义和语句:structstudent{intage;intnum;};structstudentstu[3]={{1001,20},{1002,19},{1003,21}};voidmain(

){structstudent*p;p=stu;…}则以下不正确的引用是(

)。A.(p++)->num B.p++ C.(*p).num D.p=&stu.ageD4.有以下程序:#include<stdio.h>structstu{intnum;charname[10];intage;};voidfun(structstu*p){ printf("%s\n",(*p).name);}main(){ structstustudents[3]={{9801,"Zhang",20},{9802,"Wang",19},

{9803,"Zhao",18}}; fun(students+2);}输出结果是

。A、ZhangB、Zhao

C、WangD、18B9.1.7动态存储分配

下列数组定义正确吗?intn=10;inta[n];错,不允许用变量表示数组长度但是在实际的编程中,经常可能出现所需的内存空间取决于实际输入的数据的情况。也就是需要动态地分配内存空间。C语言提供动态内存管理函数函数形式:(类型说明符*)malloc(size)功能:在内存的动态存储区中分配一块长度为“size”字节的连续区域。(类型说明符*)用于强制类型转换。函数的返回值为该区域的首地址(指针形式)。1.分配内存空间函数mallocpc=(char*)malloc(100);

分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。函数形式:(类型说明符*)calloc(n,size)

功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。2.分配内存空间函数calloc

ps=(structstu*)calloc(2,sizeof(structstu));

其中的sizeof(structstu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。函数形式:

free(void

*ptr);功能:释放指针ptr所指向的内存空间。

如:free(pc);free(ps);3.释放内存空间函数free以上3个函数均包含在头文件stdlib.h中#include<stdlib.h>9.1.8结构体与链表链表是指将若干个数据项按一定的原则连接起来的表。其中每一个数据称为节点。链表连接的原则是:前一个节点指向下一个节点;那么结构体与链表有什么关系呢?structentry{intvalue;//存放整数

structentry*next;//指向entry结构的; };100200300节点一节点二节点三怎样表示节点以及节点之间的关系?创建链表

structentryn1,n2,n3;执行下列语句可使n1结构的next指针指向n2结构。n1.next=&n2;下列语句可加入n3节点。

n2.next=&n3;n1.valuen1.nextn2.valuen2.next100200n1.valuen1.nextn2.valuen2.nextn3.valuen3.next100200300【例9.7】#include<stdio.h>main(){structentry { intvalue;

structentry*next; };

structentryn1,n2,n3; inti; n1.value=100; n2.value=200; n3.value=300; n1.next=&n2; n2.next=&n3; i=n1.next->value; printf("%d\n",i); printf("%d\n",n2.next->value);

}结果输出:200

300n1.valuen1.nextn2.valuen2.nextn3.valuen3.next链表结点的删除语句:n1.next=n2.next;或n1.next=&n3;链表结点的插入n1.valuen1.nextn2.valuen2.nextn3.valuen3.nextn2_3.valuen2_3.next语句:n2_3.next=&n3;n2.next=&n2_3链表练习:1、设有以下语句:structst{ intn; structst*next;};staticstructsta[3]={5,&a[1],7,&a[2],9,'\0'},*p;p=&a[0];则表达式()的值是6。A、p++->nB、p->n++C、(*p).n++D、++p->nD9.有以下结构体变量的定义,如图所示,指针p指向变量a,指针q指向变量b,则不能把节点b链接到节点a之后的语句是()。structnode{chardata;structnode*next;}a,b,*p=&a,*q=&b;A.a.next=q; B.p.next=&b; C.p->next=&b; D.(*p).next=q;B2、分析以下程序的输出结果。#include<stdio.h>#include<string.h>#include<malloc.h>structSTUD{ intno; char*name; intscore;};main(){ structSTUDst1={1,"Mary",85},st2; st2.no=2;=(char*)malloc(sizeof(10)); strcpy(,"Smith"); st2.score=78; printf("%s\n",(st1.score>st2.score?:));}Mary3、分析以下程序的输出结果。#include<stdio.h>#include<stdlib.h>structSTUD{intno;structSTUD*next;};main(){ structSTUD*p,*q;inti;p=q=(structSTUD*)calloc(3,sizeof(structSTUD)); for(i=1;i<=3;i++)(p++)->no=i*100; for(i=1;i<=3;i++) printf("%d\n",(q++)->no);printf("\n");}1002003009.3共用体

编号no姓名name性别sex职业prof学号num职务title1LiXiaoM学生201701012JinF学生201701023FengF教师讲师4RongM教师副教授设有下列若干人员的数据,请用相应数据结构表示:可以看出,学生和教师所包含的最后一列数据是不同的,怎样表示这样的数据结构?共用体共用体(union)把几种不同类型的值存放在同一内存区域中,例如,把一个整型值和字符值放在同一区域中,既能以整数存取,又能以字符存取。定义一个共用体类型的一般形式为:union共用体名{成员列表;};成员表中含有若干成员,成员的一般形式为:

类型说明符

成员名例2:uniondata{inti;charch;floatf;};

一、共用体的定义例1:unionprof{inti;chartitle[10];};

二、共用体变量的说明

共用体变量的说明和结构变量的说明方式相同,也有三种形式。先定义,再说明定义同时说明直接说明

uniondata{inti;charch;floatf;};uniondataa,b;union{inti;charch;floatf;}a,b;uniondata{inti;charch;floatf;}a,b;uniondata{inti;charch;floatf;}a,b;

图9.11共用体存储结构三、共用体的存储结构共用体变量的占用内存空间的大小等于成员中最长的成员所占用的内存的长度。结构体与共用体区别:存储方式不同structnode{charch[2];intk;}a;unionnode{charch[2];intk;}b;achkbchk变量的各成员同时存在任一时刻只有一个成员存在联系:两者可相互嵌套三、共用体变量的赋值和使用对共用体变量的赋值,使用都只能是对变量的成员进行。共用体变量的成员表示为:共用体变量名.成员名

#include"stdio.h"voidmain(){inti; unionab {inta; charb; charc[4]; }c; c.a=0x12345678;printf("a:%x\nch:%x\n",c.a,c.b); for(i=0;i<=3;i++)printf("ch[%d]=%x\n",i,c.c[i]);}运行结果:a:12345678b:78c[0]=78c[1]=56c[2]=34c[3]=12共用体类型数据的特点:(1)同一个内存段可以用来存放几种不同类型的数据,但在某一时刻只能存放其中一种;(2)共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。

如:c.a=200;c.b=‘a’;

此时printf(“%d”,c.a);输出:97(3)初始化共用体变量时只能赋一个初值;unionab {inta; charb; charc[4]; }c={200,'a',"abc"};上述赋值是错误的正确的初始化为:

unionab {inta; charb; charc[4]; }c={'a'};9.4枚举

枚举是一个被命名的整型常数的集合,枚举在日常生活中很常见。例如表示星期的SUN,MON,TUE,WED,THU,FRI,SAT枚举的说明形式为:enum

枚举名标识符{常量标识符[=整型常数],常量标识符[=整型常数],...常量标识符[=整型常数],}枚举变量;如果枚举没有初始化,即省略"=整型常数"时,则从第一个标识符开始,顺序给每个标识符一个序列号0,1,2,...。但当枚举中的某个成员赋值后,其后的成员则按此数值依次加1作为其序列号。

例如:enumstring{x1,x2,x3,x4}x;x1,x2,x3,x4的值分别为0,1,2,3。当定义改变成:enumstring{x1,x2=0,x3=50,x4,}x;则x1=0,x2=0,x3=50,x4=51

注意:

1.

枚举中每个成员(标识符)结束符是",",

不是";",最后一个成员可省略","。2.

初始化时可以赋负数,其后的标识符仍依次加1。3.

枚举变量只能取枚举说明结构中的某个标识符常量。例如:enumstring{x1=5,x2,x3,x4,};enumstrigx=x3;此时,枚举变量x实际上是7。但不能直接赋值为整数常量:enumstrigx=7;错误

9.5自定义数据类型功能:用自定义名字为已有数据类型命名类型定义简单形式:typedeftype

name;例typedefintINTEGER;类型定义语句关键字已有数据类型名用户定义的类型名例typedeffloatREAL;类型定义后,与已有类型一样使用例INTEGERa,b,c;REAL

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论