结构体、共用休和用户定义类型.ppt

上传人:zhu****ei 文档编号:3523063 上传时间:2019-12-17 格式:PPT 页数:47 大小:445KB
返回 下载 相关 举报
结构体、共用休和用户定义类型.ppt_第1页
第1页 / 共47页
结构体、共用休和用户定义类型.ppt_第2页
第2页 / 共47页
结构体、共用休和用户定义类型.ppt_第3页
第3页 / 共47页
点击查看更多>>
资源描述
全国计算机等级考试2C课程,第十一讲结构体、共用体和用户定义类型,2019/12/17,作者:张旭仟版权所有欢迎盗版,2,结构体的概念,与数组相比,结构体是一种功能更为强大的构造类型数据。结构体类型可以把不同类型的数据组合成一个整体。定义方法:struct结构体名数据类型1成员名1;数据类型2成员名2;数据类型n成员名n;,说明:struct是定义结构体类型的关键字;结构体名、成员名是合法的用户标识符,结构体名可省略(无名结构体)数据类型n成员名n可以是基本类型也可以是其他构造类型;同一结构体中成员名不可同名;结构定义语句的分号不可省略;结构体类型定义只是规定了该结构体类型的组成形式,编译程序并不会给结构体类型分配存储空间。,2019/12/17,作者:张旭仟版权所有欢迎盗版,3,结构体类型和结构体变量的定义,应先定义结构体类型,再定义结构体变量,如:structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;structstudentstu1,stu2;,又如:#defineSTUDENTstructstudentSTUDENTintnum;charname20;charsex;intage;floatscore;charaddr30;STUDENTstu1,stu2;,2019/12/17,作者:张旭仟版权所有欢迎盗版,4,结构体类型和结构体变量的定义,也可以直接定义结构体变量。一般形式:struct类型标识符成员名;类型标识符成员名;变量名表列;,如:structintnum;charname20;charsex;intage;floatscore;charaddr30;stu1,stu2;,本例中,结构体类型没有被命名,这称为无名结构体。无名结构体可以用来直接定义变量,但本类型只能使用一次,后面无法再用。,2019/12/17,作者:张旭仟版权所有欢迎盗版,5,结构指针变量的定义,结构指针变量说明的一般形式为:struct结构名*结构指针变量名例如,在前面的例题中定义了stu这个结构,如要说明一个指向stu的指针变量pstu,可写为:structstu*pstu;当然也可在定义stu结构时同时说明pstu。结构指针变量也必须要先赋值后才能使用。赋值是把结构变量的首地址赋予该指针变量。要特别注意的是,不能把结构类型名赋予一个指针变量。如果boy是被说明为stu类型的结构变量,则:pstu=charname20;charsex;intage;floatscore;charaddr30;,注意:这是结构体定义,只描述结构的组织形式,student是结构体类型名,编译时并不为它分配内存,结构体只有在实例化时才为每个结构体成员分配内存。,2019/12/17,作者:张旭仟版权所有欢迎盗版,8,结构体类型和结构体变量的定义,结构体中的成员(即“域”),可以是普通变量也可以是一个结构体变量。也就是说结构体可以嵌套使用。,如:structdateintmonth;intday;intyear;structstudentintnum;charname20;structdatebirthday;stu;,或:structstudentintnum;charname20;structdateintmonth;intday;intyear;birthday;stu;,2019/12/17,作者:张旭仟版权所有欢迎盗版,9,结构体变量的初始化,形式一:struct结构体名类型标识符成员名;类型标识符成员名;.;struct结构体名结构体变量=初始数据;,例:structstudentintnum;charname20;charsex;intage;charaddr30;structstudentstu1=112,“WangLin”,M,19,“200BeijingRoad”;,2019/12/17,作者:张旭仟版权所有欢迎盗版,10,结构体变量的初始化,形式二:struct结构体名类型标识符成员名;类型标识符成员名;.结构体变量=初始数据;,例structstudentintnum;charname20;charsex;intage;charaddr30;stu1=112,“WangLin”,M,19,“200BeijingRoad”;,2019/12/17,作者:张旭仟版权所有欢迎盗版,11,结构体变量的初始化,形式三:struct类型标识符成员名;类型标识符成员名;.结构体变量=初始数据;,例:structintnum;charname20;charsex;intage;charaddr30;stu1=112,“WangLin”,M,19,“200BeijingRoad”;,2019/12/17,作者:张旭仟版权所有欢迎盗版,12,结构体变量的引用,在定义了结构体变量以后,当然可以引用这个变量。引用规则:结构体中的成员只能单独使用,它的作用与地位相当于普通变量。引用方式有三种:结构体变量名.成员指针变量名-成员(*指针变量名).成员其中成员(分量)运算符“.”,结构指向运算符“-”,与前面已经接触过的下标运算符、圆括号运算符()的优先级均为1,结合性从左向右,2019/12/17,作者:张旭仟版权所有欢迎盗版,13,结构体变量的引用,使用成员(分量)运算符“.”引用结构体成员,如:structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;stu1,stu2;stu1.score=85.5;stu1.num=10;stu1.score+=stu2.score;stu1.age+;,2019/12/17,作者:张旭仟版权所有欢迎盗版,14,结构体变量的引用,使用结构指针变量,往往能更方便地访问结构变量的各个成员,其访问的一般形式为:(*结构指针变量).成员名或为:结构指针变量-成员名例如:(*pstu).num或者:pstu-num应该注意,(*pstu)两侧的括号不可少,因为成员符“.”的优先级高于“*”。如去掉括号写作*pstu.num则等效于*(pstu.num),这样,意义就完全不对了。,2019/12/17,作者:张旭仟版权所有欢迎盗版,15,结构体变量的引用,示例:结构指针变量的具体说明和使用方法,structstuintnum;char*name;charsex;floatscore;boy1=102,Zhangping,M,78.5,*pstu;main()pstu=,2019/12/17,作者:张旭仟版权所有欢迎盗版,16,结构体变量的引用,例中,printf语句试图整体引用结构体变量stu1的用法是不可行的。,举例:structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;stu1,stu2;printf(“%d,%s,%c,%d,%f,%sn”,stu1);,说明:(1)不能将一个结构体变量作为一个整体进行输入和输出。,2019/12/17,作者:张旭仟版权所有欢迎盗版,17,结构体变量的引用,说明:(2)但是,将一个结构体变量赋值给另一个结构体变量是允许的,如:structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;stu1,stu2;stu1=stu2;,2019/12/17,作者:张旭仟版权所有欢迎盗版,18,结构体变量的引用,说明:(3)对于嵌套的结构体,内部成员可以逐级引用,例:structstudentintnum;charname20;structdateintmonth;intday;intyear;birthday;stu1,stu2;stu1.birthday.month=12;,2019/12/17,作者:张旭仟版权所有欢迎盗版,19,结构体变量的引用,说明:(4)不能对结构体变量做关系运算,例:structstudentintnum;charname20;charsex;intage;floatscore;charaddr30;stu1,stu2;if(stu1=stu2),例中,语句if(stu1=stu2)是错误的,2019/12/17,作者:张旭仟版权所有欢迎盗版,20,函数之间结构体变量的数据传递,函数之间结构体变量的数据传递分以下几种情况(1)向函数传递结构体变量的成员(2)向函数传递结构体变量(3)向函数传递结构体的指针例如:通过函数给结构体成员赋值,#includestdio.hstructABchara10;intb;getdata(structAB*p)scanf(%s%d,2019/12/17,作者:张旭仟版权所有欢迎盗版,21,动态存储分配,动态存储分配的概念变量、数组一旦定义,其存储长度在整个程序中是固定不变的,因此被称为“静态存储分配”。然而,实际编程中,有时候所需的内存空间取决于实际输入的数据,无法预先确定。为了解决上述问题,语言提供了一些内存管理函数,可以按需要动态地分配内存空间,也可把不再使用的空间回收(释放),这种机制称为“动态存储分配”。常用的动态存储分配函数有以下三个:分配内存空间函数malloc分配内存空间函数calloc释放内存空间函数free使用以上函数必须有文件包含命令:#includestdlib.h,2019/12/17,作者:张旭仟版权所有欢迎盗版,22,动态存储分配,分配内存空间函数malloc调用形式:(类型说明符*)malloc(size)功能:在内存的动态存储区中分配一块长度为size字节的连续区域。函数的返回值为该区域的首地址。其中“类型说明符”表示把该区域用于何种数据类型。(类型说明符*)表示把返回值强制转换为该类型指针。“size”是一个无符号数。例如:char*pc;pc=(char*)malloc(100);表示动态分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。,2019/12/17,作者:张旭仟版权所有欢迎盗版,23,动态存储分配,分配内存空间函数calloccalloc也用于分配内存空间。调用形式:(类型说明符*)calloc(n,size)功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。(类型说明符*)用于强制类型转换。calloc函数与malloc函数的区别仅在于一次可以分配n块区域。例如:structstu*ps=(struetstu*)calloc(2,sizeof(structstu);其中的sizeof(structstu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。,2019/12/17,作者:张旭仟版权所有欢迎盗版,24,动态存储分配,释放内存空间函数free调用形式:free(void*ptr);功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc或calloc函数所分配的区域。例如:free(pc);free(ps);,2019/12/17,作者:张旭仟版权所有欢迎盗版,25,动态链表的概念,如果采用动态分配的办法存储学生记录,一次为一条记录分配一块空间(我们称之为结点),这样就无须预先确定学生的准确人数。如果某学生退学,也可删去该结点,并释放该结点占用的存储空间。每个结点之间物理上可以是不连续的。结点之间的联系用指针实现,即在结点结构中定义一个成员项存放下一结点的首地址,这个成员,称为指针域。在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个结点的首地址,如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,其指针域置为空(NULL)。这样一种连接方式,在数据结构中称为“链表”。,2019/12/17,作者:张旭仟版权所有欢迎盗版,26,动态链表的概念,链表的组成:链表中的所有结点都是同一种结构类型。包括一个头指针,是一个结构类型的指针变量,用来存放链表第一个结点的首地址;若干个结点,用来存放用户需要的实际数据以及链接节点的指针。下图为一简单链表的示意图,头结点head没有数据域,只负责存放第一个结点的首地址。除head外,每个结点都分为两个域,其中数据域存放各种实际的数据,如学号、姓名等;指针域存放下一结点的首地址。,2019/12/17,作者:张旭仟版权所有欢迎盗版,27,动态链表的概念,链表的结点链表的结点都是结构体类型,如structstudentintnum;floatscore;structstudent*next;其中成员num和score用来存放结点中用户需要用到的数据;next是指针类型的成员,它指向structstudent类型数据(也就是next所在的结构体类型),2019/12/17,作者:张旭仟版权所有欢迎盗版,28,链表操作的建立与操作实例,定义链表的结点结构,typedefstructnodecharname20;structnode*link;stud;,这样就定义了一个单链表的结构,其中charname20是一个用来存储姓名的字符型数组,指针*link是一个用来存储其直接后继的指针。定义好了链表的结构之后,就可以在数据域中存储适当的数据,如有后继结点,则把链域指向其直接后继,若没有,则置为NULL。,2019/12/17,作者:张旭仟版权所有欢迎盗版,29,链表的建立与操作实例,创建链表,stud*creat(intn)stud*p,*h,*s;inti;if(h=(stud*)malloc(sizeof(stud)=NULL)printf(不能分配内存空间!);returnNULL;h-name0=0;/*把表头结点的数据域置空*/h-link=NULL;/*把表头结点的链域置空*/p=h;/*p指向表头结点*/for(i=0;ilink=s;printf(请输入第%d个人的姓名,i+1);scanf(%s,s-name);s-link=NULL;p=s;return(h);,注意:由于用到malloc函数,所以在程序的开始部分应有如下包含命令:#include,2019/12/17,作者:张旭仟版权所有欢迎盗版,30,链表的建立与操作实例,创建遍历链表的函数,main()stud*head;head=creat(3);list(head);,voidlist(stud*head)stud*p,*q;p=head;while(p-link!=NULL)q=p-link;printf(%sn,q-name);p=q;,调用创建和输出链表的主函数,2019/12/17,作者:张旭仟版权所有欢迎盗版,31,链表的建立与操作实例,根据数据项的值检索链表中的结点思路:对单链表的结点依次扫描,检测其数据域是否是我们所要查好的值,若是返回该结点的指针,否则返回NULL。,stud*search(stud*head,char*x)stud*p;char*y;p=head-link;while(p!=NULL)y=p-name;if(strcmp(y,x)=0)return(p);elsep=p-link;if(p=NULL)printf(没有查找到该数据!);returnNULL;,2019/12/17,作者:张旭仟版权所有欢迎盗版,32,链表的建立与操作实例,测试结点检索函数的主函数,main()charfullname20;stud*head,*searchpoint;head=creat(3);printf(请输入你要查找的人的姓名:);scanf(%s,fullname);searchpoint=search(head,fullname);printf(你要查找的人的姓名:%sn,searchpoint-name);,2019/12/17,作者:张旭仟版权所有欢迎盗版,33,链表的建立与操作实例,在单向链表中插入新结点在单向链表中插入新结点的步骤如下:(1)先创建一个新结点,并用指针p指向该结点。(2)将q指向的结点的next域的值(即q的后继结点的指针)赋值给p指向结点的next域。(3)将p的值赋值给q的next域。通过以上3步就可以实现在链表中由指针q指向的结点后面插入p所指向的结点。可以通过图1-5形象地展示出这一过程。,2019/12/17,作者:张旭仟版权所有欢迎盗版,34,链表的建立与操作实例,在单向链表中插入新结点,voidinsert(stud*p)charstuname20;stud*s;if(s=(stud*)malloc(sizeof(stud)=NULL)printf(不能分配内存空间!);exit(0);printf(输入要插入学生结点的姓名:);scanf(%s,stuname);strcpy(s-name,stuname);s-link=p-link;p-link=s;,2019/12/17,作者:张旭仟版权所有欢迎盗版,35,链表的建立与操作实例,测试插入结点函数的主函数,main()charfullname20;stud*head,*searchpoint;head=creat(2);printf(输入要在他之后添加结点的那个人的姓名:);scanf(%s,fullname);searchpoint=search(head,fullname);insert(searchpoint);list(head);,2019/12/17,作者:张旭仟版权所有欢迎盗版,36,链表的建立与操作实例,删除单向链表中的结点在链表内删除节点又三种不同的情形:1删除第一个节点:只需要将head指向第二个节点2删除最后一个节点,只需要将指向最后一个节点的指针(引用)指向NULL3删除中间节点,只要将需要删除节点的指针指向需要删除节点的下一个节点。,stud*del(stud*head,stud*x)stud*p;if(head=x)returnhead-link;elsep=head;while(p-link!=x)p=p-link;if(x-link=NULL)p-link=NULL;elsep-link=x-link;returnhead;,2019/12/17,作者:张旭仟版权所有欢迎盗版,37,链表的建立与操作实例,测试删除结点函数的主函数,main()charfullname20;stud*head,*searchpoint;head=creat(3);printf(请输入要删除的学生的姓名:);scanf(%s,fullname);searchpoint=search(head,fullname);del(head,searchpoint);,2019/12/17,作者:张旭仟版权所有欢迎盗版,38,链表的建立与操作实例,销毁一个链表链表使用完毕后建议销毁它,因为链表本身会占用内存空间。如果一个系统中使用了很多链表,而使用完毕后又不及时销毁它,那么这些垃圾空间积累过多,最终可能导致内存泄漏甚至程序崩溃。,voiddestroy(stud*head)stud*p,*q;p=head;while(p!=NULL)q=p-link;free(p);p=q;head=NULL;,2019/12/17,作者:张旭仟版权所有欢迎盗版,39,共用体的定义,共用体也叫联合体,也是一种构造数据类型。共用体可以使几个不同类型的变量共占同一段内存。定义形式:union共用体名类型标识符成员名;类型标识符成员名;.;其中union是关键字,共用体名是用户自定义标示符。,例:uniondatainti;charch;floatf;,注意:这里的类型定义在编译时也是不分配内存的。,2019/12/17,作者:张旭仟版权所有欢迎盗版,40,共用体变量的定义,形式一:uniondatainti;charch;floatf;uniondataa,b;形式二:uniondatainti;charch;floatf;a,b;,共用体变量任何时刻只有一个成员存在。共用体变量在编译时被分配内存,长度=最长成员所占字节数。,形式三:unioninti;charch;floatf;a,b;,2019/12/17,作者:张旭仟版权所有欢迎盗版,41,共用体变量的引用,引用方式:共用体变量名.成员名共用体指针名-成员名(*共用体指针名).成员名,例:如有以下定义uniondatainti;charch;floatf;uniondataa,b,c,*p,d3;,a.i、a.ch、a.fp-i、p-ch、p-f(*p).i、(*p).ch、(*p).fd0.i、d0.ch、d0.f,则可以如下方式加以引用:,2019/12/17,作者:张旭仟版权所有欢迎盗版,42,共用体变量的引用,引用规则不能直接引用共用体变量,只能引用其成员。,例:unioninti;charch;floatf;a;a=1;/*以上语句是错误的*/,例:unioninti;charch;floatf;a=1,a,1.5;/*以上赋值语句是错误的*/,不能在定义共用体变量的同时对其初始化。,2019/12/17,作者:张旭仟版权所有欢迎盗版,43,共用体变量的引用,共用体变量中起作用的成员是最后一次存放的成员,例:uniondatainti;charch;floatf;uniondataa;a.ch=a;a.f=1.5;printf(%d,a.i);,运行结果:1.5,可以用一个共用体变量为另一个变量赋值,例:floatx;unioninti;charch;floatf;a,b;a.i=1;a.ch=a;a.f=1.5;b=a;()x=a.f;(),2019/12/17,作者:张旭仟版权所有欢迎盗版,44,共用体举例,将一个整数按字节输出,main()unionint_charshorti;charch2;x;x.i=24897;printf(i=%on,x.i);printf(ch0=%o,ch1=%onch0=%c,ch1=%cn,x.ch0,x.ch1,x.ch0,x.ch1);,运行结果:i=60501ch0=101,ch1=141ch0=A,ch1=a,2019/12/17,作者:张旭仟版权所有欢迎盗版,45,用typedef定义的类型,typedef的功能用自定义的名字为已有的数据类型重新命名类型定义后,可以与已有的类型一样使用定义形式:typedeftypename;其中:typedef是类型定义语句关键字type为已有数据类型名name是用户自定义的类型名,例:typedefintINTEGER;typedeffloatREAL;,类型定义后,就可以与已有的类型一样使用,2019/12/17,作者:张旭仟版权所有欢迎盗版,46,用typedef定义的类型,说明:typedef没有并创造新的数据类型typedef只能定义类型,不能定义变量typedef与define不同,2019/12/17,作者:张旭仟版权所有欢迎盗版,47,Thanklisten!,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!