C语言程序设计项目化教程课件-模块7_第1页
C语言程序设计项目化教程课件-模块7_第2页
C语言程序设计项目化教程课件-模块7_第3页
C语言程序设计项目化教程课件-模块7_第4页
C语言程序设计项目化教程课件-模块7_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

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

文档简介

模块七图书信息的添加、浏览和删除模块学习目标1、理解和掌握结构体的定义和调用方法;2、理解和掌握结构体数组的定义和引用;3、理解共用体和枚举类型的构造、定义和引用。项目三图书信息管理系统

模块七

图书信息的添加、浏览和删除

7.1结构体

7.1结构体7.1.1结构体的概念与声明7.1.2结构体变量7.1.3结构体数组7.1.4结构体指针7.1.1结构的概念与定义1.结构的概念及定义声明一个结构类型的一般形式为:struct结构名{ 类型名成员名1; 类型名成员名2; …… 类型名成员名n;};说明:(1)关键字struct与结构名一起构成结构类型名。(2)大括号中的内容是结构所包括的成员,也叫结构分量。成员的数据类型都可以是基本类型,也可以是结构类型。(3)结构类型定义只是说明了结构类型的构成情况,系统并不分配内存空间。(4)定义结构类型时,不允许将成员的数据类型定义成自身的结构类型,但是结构类型中可以含有指向自身类型的指针变量。(5)C语言把结构声明看做是一条语句,括号后面的分号是不可少的。1.结构变量的定义声明了结构类型后,还需要定义结构变量,以便在程序中引用它。结构变量和其他变量一样,必须先定义后使用。7.1.2结构变量(1)先定义结构类型,再定义结构变量例如:structbooks{ intbno;charbname[20],field[10],author[10],publisher[30]; floatprice;};structbooksbook1,book2;(2)定义结构类型的同时定义结构变量例如:structbooks{intbno;charname[20],field[10],author[10],publisher[30];floatprice;}book1,book2;(3)直接定义结构变量struct{ intbno; charbname[20],field[10]; floatprice;}book1,book2;说明:方式(3)中没有给出结构名,在此定义语句后面无法再定义这个类型的其他结构变量。

【课堂思考】下面关于结构的定义语句,错误的是________。A.structtest{inta;intb;intc;};structtesty;B.structtest{inta;intb;intc;}structtesty;C.structtest{inta;intb;intc;}y;D.struct{inta;intb;intc;}y;2.结构变量的初始化结构变量在定义的同时也可以进行初始化。结构变量初始化的一般形式是在定义变量的后面加上“={初值表列};”。除了允许具有相同类型的结构变量相互赋值以外,不能整体引用结构变量,而只能引用结构变量中的成员。结构变量的成员与普通变量一样可以参与各种运算,对结构变量的赋值、存取、运算都是通过引用其成员进行的。3.结构变量的引用引用结构变量成员的方式为:结构变量名.成员名其中,“.”是成员运算符。在C语言中,成员运算符“.”的优先级高于其他运算符,其结合方向是从左到右。例如,表达式“book1.price++”相当于“(book1.price)++”。【例01】结构变量初始化示例#include<stdio.h>intmain(){ structbooks /*结构类型*/ { intbno; charbname[20],field[10],author[10],publisher[30]; floatprice; };

structbooksbk1={ /*初始化*/

1001,"cprogramming","computer","xuwei","renminyoudianpress",39.0

}; printf("bno=%d\nbname=%s\nfield=%s\n",bk1.bno,bk1.bname,bk1.field); printf("author=%s\n",bk1.author); printf("publisher=%s\nprice=%f\n",bk1.publisher,bk1.price); return0;}注意:(1)对结构变量初始化时,需要按照其成员出现的顺序对每个成员依次赋值,不能跳过前面的成员给后面的成员赋值,例如下面的用法是错误的。structbooksbk1={1002,,"computer",,"renminyoudianpress",39.0};(2)不能在结构内部给成员赋初值,例如下面的用法是错误的。structbooks{ intbno=1001; charbname[20]="cprogramming"; charfield[10]="computer"; charauthor[10]; charpublisher[30]; floatprice=23;};7.1.3结构数组1.结构数组的定义可以将数组定义为结构类型,即结构数组结构数组用来表示具有相同数据结构的一个群体,可以使用循环对数组元素进行统一处理,优化算法。(1)先声明结构类型,再定义结构数组struct结构名{ 成员列表;};struct结构名数组名[元素个数];(2)声明结构类型的同时定义结构数组struct结构名{ 成员列表;}数组名[元素个数];(3)直接定义结构数组struct{ 成员列表;}数组名[元素个数];2.结构数组的初始化结构数组初始化的一般形式为:struct结构名数组名[元素个数]={初值表列};例如:structbooksbook[5]={101,"clanguage","computer","xw","rmydpress",39,102,"vbprogramming","computer","zys","qhdxpress",39,103,"java","computer","mj","jxgypress",34};为了增强程序的可读性,最好用大括号将每一个数组元素的初值括起来。例如:structbooksbook[5]={ {101,"clanguage","computer","xw","rmydpress",39}, {102,"vb","computer","zys","qhdxpress",39}, {103,"java","computer","mj","jxgypress",34}, {104,"c#","math","chc","dzgypress",29.8}, {105,"clanguage","computer","thq","qhdxpress",26}};当对结构数组的全部元素进行初始化时,可以省略数组的长度,系统根据初始化数据的多少来确定数组的长度。例如:structbooksbook[]={ {101,"clanguage","computer","xw","rmydpress",39}, {102,"vb","computer","zys","qhdxpress",39}, {103,"java","computer","mj","jxgypress",34}, {104,"linearalgebra","math","chc","dzgypress",29.8}, {105,"clanguage","computer","thq","qhdxpress",26}};根据初值可知结构数组book的长度为53.结构数组的使用结构数组元素成员的引用可以有如下几种形式:(1)结构数组名[下标].成员名(2)(*(结构数组名+下标)).成员名(3)(结构数组名+下标)->成员名。其中:形式(2)中最外面的括号不可少形式(3)中的“->”称为指向成员运算符,其优先级与成员运算符“.”相同,且结合方向均为从左到右。结构数组元素成员的使用方法与同类型的结构变量相同。#include<stdio.h>/*包含头文件*/intmain()/*主函数main*/{ structbooks{/*声明结构体变量books*/ intnum; charbook_name[20]; charauthor[10]; doubleprice; };structbooksbook[3]={/*定义结构体数组*/ {1001,"Cprogram","James",45.00}, {1002,"Javaprogram","Tom",55.00}, {1003,"javascript","Jack",65.00} };printf("%d\n",book[0].num);printf("%d\n",book[1].num);printf("%d\n",book[2].num);return0;/*程序结束*/}运行结果:100110021003指向结构变量的指针叫做结构指针。结构指针变量的值是它所指向的结构变量所占用内存空间的起始地址。结构指针变量定义的形式为:struct结构名*指针变量名;7.1.4结构体指针1、结构指针的概念访问结构变量的成员的形式等价:(1)结构变量名.成员名(2)(*结构指针变量名).成员名(3)结构指针变量名->成员名例如,设有如下定义:structstru{ intn;}str,*p=&str;则:str.n:得到结构变量str的成员n的值。(*p).n:得到p指向的结构变量str的成员n的值。p->n:得到p指向的结构变量str的成员n的值。p->n++:得到p指向的结构变量str的成员n的值,然后使成员n的值加1。++p->n:等价于++(p->n),使p指向的结构变量str的成员n的值加1。(++p)->n:先使p自加1,然后得到它指向的元素的成员n的值。(p++)->n:先得到p->n的值,然后使p自加1。【例03】结构指针使用示例。#include<stdio.h>intmain(){structbooks {intbno;charbname[20],field[10],author[10],publisher[30];floatprice;};structbooksbk1={1001,"cprogramming","computer","xuwei","renminyoudianpress",39.0}; structbooks*p=&bk1;printf("bno=%d,bname=%s,price=%f\n",bk1.bno,(*p).bname,p->price);return0;}运行结果:bno=1001,bname=cprogramming,price=39.000000结构指针也可以用来指向一个结构数组,这时结构指针的值是结构数组的首地址。同样,结构指针变量也可以指向结构数组元素,此时结构指针变量的值是结构数组元素的地址。2、指向结构数组的指针例如,结构数组与结构指针的定义如下:struct{ inta; floatb;}a[3],*p;p=a;此时p指向数组a的第一个元素,“p=a;”等价于“p=&a[0];”,若执行“p++;”则此时指针变量p指向a[1]。pp++a[0]a[1]a[2]#include/*包含头文件*/intmain()/*主函数main*/{structbooks{/*声明结构体books*/intnum;charbook_name[20];charauthor[10];doubleprice;};structbooksbook[3]={/*定义结构体数组*/{1001,"Cprogram","James",45.00},{1002,"Javaprogram","Tom",55.00},{1003,"javascript","Jack",65.00}};structbooks*p=book;/*定义结构体指针变量并指向结构体数组*/printf("%d\n",(*p).num);p++;printf("%d\n",(*p).num);return0;/*程序结束*运行结果:10011002【例04】指向结构体数组的指针项目三图书信息管理系统

模块七

图书信息的添加、浏览和删除

7.2链表

7.2链表7.2.1链表的概念7.2.2链表的基本操作链表是一种动态数据结构,它使用随机分配的内存单元来存放数据,这些内存单元可以是连续的,也可以是不连续的。链表是由若干个相同结构类型的元素依次串接而成的,它使用指针来表示两个元素之间的前后关系。7.2链表1、

链表的概念链表中的每个元素称为一个“结点”。结点是结构类型,其成员由两部分组成:用户需要使用的数据(称为数据成员或数据域);下一个结点的地址(称为指针域,为指向自身结构类型的指针)。链表的尾结点由于无后续结点,在其指针域放一个NULL(表示空地址),表明链表到此结束。单链表:链表的每个结点中只包含一个指针域,该指针域中存放的是其后继结点的地址,这样的链表称为单链表。h1a2b3c4dNULL单链表结点数据类型的定义形式如下:struct结构名{类型名成员名1; 类型名成员名2; …… 类型名成员名n;

struct结构名*指针名1,*指针名2,……,*指针名n;};动态内存分配是指在程序运行时动态地分配或者回收内存空间的方法,其好处是能有效地使用内存,而且同一段内存可以有不同的用途,使用时申请,用完就释放。包括三个方面的内容:动态内存分配、动态内存调整和动态内存释放。使用动态内存分配函数需要包含头文件“stdlib.h”、“malloc.h”或者“alloc.h”。2、动态内存分配(1)动态内存分配函数malloc()和calloc()说明:malloc()或calloc()函数的返回值是一个(void*)类型的指针,在使用前需要将函数的返回值转换到特定指针类型,赋给一个指针。例如,常见的使用方法为:if((p=(int*)malloc(n*sizeof(int)))==NULL){printf("Notabletoallocatememory.allocatememoryerror.\n");exit(1);}【例01】计算n个数的平均值,数字由用户在运行时输入。#include<stdio.h>#include<stdlib.h>intmain(){inti,j=0,*p;floatsum=0;printf("请输入数的个数:");scanf("%d",&i); p=(int*)malloc(i*sizeof(int)); /*或者p=(int*)calloc(i,sizeof(int))*/if(p) {while(j++<i){printf("第%d个数是:",j); scanf("%d",p++);} for(j=i;j>0;j--) sum+=*(p-j);printf("平均值是:%f",(sum/i)); free(p-i); }elseprintf("内存分配错误!");return0;}运行结果:请输入数的个数:3第1个数是:1第2个数是:2第3个数是:3平均值是:2.000000单链表的基本操作主要有:(1)创建链表(2)输出链表(3)查找结点(4)插入结点(5)删除结点(6)重组链表

7.2.2链表的基本操作链表的建立向链表中添加一个新节点data=Anodedata=Bnodedata=C∧nodehead空指针NULL表示链表结尾链表的头指针:访问链表的关键链表的建立若原链表为空表(head==NULL),则将新建节点p置为头节点head(1)head=pdatanextp新建节点(2)pr=p∧pr(3)pr->next=NULLdatanext新建节点p链表的建立若原链表为非空,则将新建节点p添加到表尾(1)pr->next=p(2)pr=p∧headdata∧prpr(3)pr->next=NULLnext链表的删除操作若原链表为空表,则退出程序若待删除节点p是头节点,则将head指向当前节点的下一个节点即可删除当前节点

datanext(1)head=p->nexthead待删除节点datanextp头节点(2)free(p)链表的删除操作若待删除节点不是头节点,则将前一节点的指针域指向当前节点的下一节点即可删除当前节点(1)pr->next=p->nextdatanextdatanext待删除节点datanextp中间节点datanext若已搜索到表尾(p->next==NULL)仍未找到待删除节点,则显示“未找到”

(2)free(p)链表的插入操作若原链表为空表,则将新节点p作为头节点,让head指向新节点phead待插入节点data∧p(1)head=pp=(structlink*)malloc(sizeof(structlink));p->next=NULL;p->data=nodeData;链表的插入操作若原链表为非空,则按节点值(假设已按升序排序)的大小确定插入新节点的位置若在头节点前插入新节点,则将新节点的指针域指向原链表的头节点,且让head指向新节点head待插入节点datanextp(2)head=pdatanextdatanextdata∧(1)p->next=headdatanext链表的插入操作若在链表中间插入新节点,则将新节点的指针域指向下一节点且让前一节点的指针域指向新节点待插入节点datanextp(2)pr->next=pdatanextdatanextdata∧(1)p->next=pr->nextprdatanext链表的插入操作若在表尾插入新节点,则末节点指针域指向新节点待插入节点datanextp(1)pr->next=pprdata∧原末节点next∧链表的输出遍历链表的所有节点headdatanextdatanextdata∧pppp∧项目三图书信息管理系统

模块七

图书信息的添加、浏览和删除

7.3共用体

7.3共用体7.3.1共用体类型的说明和变量7.3.2共用体变量的引用共用体,也叫联合体,是一种用户自定义的构造数据类型,它使几个不同类型的变量共占同一段内存。共用体实质上是采用了覆盖技术,使几个变量互相覆盖。7.3共用体1.共用体的定义注意:在C语言中,数据的存取必须与数据类型相匹配,否则会引起数据存取混乱,导致数据读写错误。共用体所占用的存储空间虽然可以存放不同类型的数据,但是在程序运行的某一个时刻只有一个成员值有效。声明一个共用体类型的一般形式为:union共用体名{ 类型名成员名1; 类型名成员名2; …… 类型名成员名n;};例如:unionelectivescore{ floatstatistics; floatmaintenance; chartourism;};方法一:先声明共用体类型,然后再定义共用体变量unionelectivescore{ floatstatistics; floatmaintenance; chartourism;};unionelectivescoreelective;2.共用体变量方法二:声明共用体类型的同时定义共用体变量unionelectivescore{ floatstatistics; floatmaintenance; chartourism;}elective;方法三:直接定义共用体变量union{ floatstatistics; floatmaintenance; chartourism;}elective;【例】若有数据类型定义如下:uniondata{ floatx; chary;};则表达式sizeof(uniondata)的值是什么?定义了共用体变量后系统会为之分配内存,共用体变量所占有的存储空间是占有存储空间最大的共用体成员所占的空间。

对于共用体变量成员的引用也是通过成员运算符“.”进行的,引用方式为:共用体变量名.成员名

例如:elective.statistics共用体和结构可以嵌套使用,即结构中的成员可以是共用体,共用体中的成员也可以是结构。引用内部成员的方式如下:

结构变量.共用体变量.成员

共用体变量.结构变量.成员对共用体变量的使用要注意下面几个问题。(1)共用体成员所占用的存储空间虽然可以存放不同类型的数据,但是在程序运行的某一个时刻只有一个成员值有效。(2)引用共用体变量时,要保证其存储类型的一致性,即最近一次存入共用体变量中的是一个整数,那么下一次取出该变量中的内容也应该是一个整数。(3)只能对共用体变量的第一个成员初始化,不能同时对共用体变量的所有成员进行初始化。【例】共用内存示例#include<stdio.h>intmain(){ unionudata { charc[2]; intx; }udd;

udd.x=0x1234; printf("udd.x=%#x\n",udd.x);

printf("udd.c[0]=%#x,udd.c[1]=%#x\n",udd.c[0],udd.c[1]); return0;}1000H1001Huddc[0]x内存分配图34H12Hc[1]运行结果:udd.x=0x1234udd.c[0]=0x34,udd.c[1]=0x12floatx;结果?【例】若有以下定义语句,则以下选项正确的是________。uniondata{ intt; floatf; charc;}d={12};intn;A.d=5; B.d={2,1.2,'a'};C.printf("%d\n",d); D.n=d;voidff(uniondatadx) { printf("%c,%x\n",dx.c,&dx.c); dx.x=10; printf("%d,%x\n",dx.x,&dx.x);}intmain(){ uniondatadd; dd.c='A'; printf("%c,%x\n",dd.c,&dd.c); ff(dd);/*函数调用,将共用体变量作为实参*/ printf("%d\n",dd.x); return0;}运行结果:A,18ff44A,18fef410,18fef4-858993599【例】共用体变量作为函数的形参【例】共用体和结构的嵌套

#include<stdio.h>unionmyun /*共用体类型*/{ struct /*共用体内部嵌套的结构类型*/ {intx,y,z; }u; intk;}a;intmain(){ a.u.x=4; a.u.y=5; a.u.z=6; a.k=0; printf("%d",a.u.x); return0;}项目三图书信息管理系统

模块七

图书信息的添加、浏览和删除

7.4枚举类型

7.4枚举类型7.4.1枚举类型的定义7.4.2枚举类型的使用7.4枚举类型1.声明声明一个枚举类型的一般形式为:enum枚举名{ 枚举值列表 };(1)关键字enum是枚举类型的标志,“enum枚举名”构成枚举类型。(2)枚举是一个集合,集合中的元素(称为枚举成员或枚举常量)是一些特定的标识符,元素之间用逗号隔开。(3)在枚举类型中,枚举成员是有值的,第一个枚举成员的默认值为0,后续成员的值依次递增。(4)枚举成员是常量,不能对它们赋值。如“red=1;”是错误的。但是在定义枚举类型时可以指定枚举成员的值。(5)同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的枚举成员。2.枚举变量声明了枚举类型后,可以使用它来定义枚举变量,有以下三种形式:形式一:先定义枚举类型,然后定义枚举变量enumcolor{red,yellow,green,blue,black};enumcolorc1,c2;形式二:定义枚举类型的同时定义枚举变量enumcolor{red,yellow,green,blue,black}c1,c2;形式三:直接定义枚举变量enum{red,yellow,green,blue,black}c1,c2;注意:枚举变量的值只能为枚举类型中列举出来的枚举成员,如“c1=red;”,则c1的值为0。枚举成员不是字符常量或字符串常量,使用时不能加单引号或双引号,如“c1="red";”是错误的。不能将一个数值直接赋值给枚举变量,如“c1=3;”是错误的。但是使用强制类型转换则可以进行赋值,如“c1=(enumcolor)3;”,其含义是将枚举类型enumcolor中值为3的成员赋值给变量c1,相当于“c1=blue;”。1.枚举类型数据的输入输出枚举类型的数据不能直接进行输入输出。输入时应先输入其序号,然后使用强制类型转换完成;输出时应先进行转换才能输出其对应的字符串。7.4.2枚举类型的使用【例01】从键盘输入一个整数,显示与该整数对应的枚举常量所表示的水果英文名称。#include<stdio.h>enumfruits{watermelon,peach,strawberry,banana,pineapple,apple};intmain(){ charfts[][20]={"watermelon","peach","strawberry","banana","pineapple","apple"}; enumfruits

温馨提示

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

评论

0/150

提交评论