




已阅读5页,还剩22页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
任务六 复杂构造数据类型的应用任务六 复杂构造数据类型的应用6.1 教学目标1. 熟练掌握结构体的定义和使用。2. 了解指向结构体变量的指针的应用。3. 掌握共用体的定义和使用。4. 了解枚举类型的定义和使用。5. 了解链表的概念和应用6.2 工作任务1. 结构体类型的使用2. 共用体类型的使用3. 枚举类型的使用4. 简单链表的应用6.3 相关实践知识6.3.1 结构体类型的使用【案例6-1】建立有10个学生成绩的结构记录(学生有学号,姓名,成绩这三个信息),输出平均分,并按照成绩从高到低的顺序输出学生记录。算法分析: 学生有学号,姓名,成绩这三个信息数据类型分别是整型,字符数组,浮点型,因为数组只能存放相同类型的数据,故不能用二维数组来描述,我们采用结构体来建立学生记录。struct student int num;char name10;float score;struct student s1;结构体类型struct student是我们自定义的数据类型,一个结构变量s1只能存放一个学生的记录,若班上有10个学生,存放10个学生的记录,需要用结构体数组:struct student stud10;数组中的每个元素都是student结构类型用for循环输入这10个学生信息,同时把每个输入的成绩加入总成绩。算出总平均成绩并输出。用选择排序算法,按成绩对结构体数组进行排序。按照成绩从高到低的顺序输出学生记录具体流程图如图6-1所示。图6-1 【案例6-1】的流程图C语言程序如下:#define N 10struct student int num; /*学号*/ char name10; /*姓名*/ float score; /*成绩*/; /*学生结构体类型声明结束*/struct student studN; /*定义学生结构体数组*/main( ) int i, j, index; float sum=0; /*index在排序时用来标记当前最小值的位置,sum放总平均成绩*/ struct student temp; /*排序时交换位置需要用到的变量*/ printf(please input num name scoren); for(i = 0; i N; i+) scanf(%d %s %f,&studi.num,,&studi.score); sum = sum + studi.score; for ( i = 0; i N-1; +i ) /*用选择排序算法进行排序*/ index =i; for (j = i+1; j N; j+) if (studj .score =0; i- ) /*从高到低的顺序输出学生记录*/ printf(num=%d,name=%s,score=%fn,studi.num, ,studi.score); 运行时把#define N 10改成#define N 2结果如下:please input num name score用户输入:1 zhouyu 882 caocao 85 输出:The average: 86.500000Num=1,name=zhouyu, score=88.00000Num=2, name=caocao, score=85.00000程序说明: struct student int num; /*学号*/ char name20; /*姓名*/ float score; /*成绩*/; 声明了一个结构体类型,该类型名字取为 student ,该类型把3种不同类型的变量捆绑在一起来描述学生信息。 struct student stud10;定义student 结构体类型的一个有10个元素的数组,名字为 stud,用来存放10个学生的信息。 scanf(%d%s,&studi.num,);结构体的每一个成员都是通过其名字来引用,引用形式如下:结构体变量名. 成员名输入的时候,整型成员num的输入地址的形式是&studi.num有&。而字符数组成员的输入地址形式是没有&,这和普通整型变量,普通字符串的输入形式是一样的。 temp=studindex; studindex=studi; studi=temp;C语言中,两个相同类型结构体变量可以相互整体赋值, 但除了整体赋值操作外,不可以对结构体变量名直接引用,只能对结构体变量中的成员分别进行引用。【案例6-2】学生成绩管理系统中有N个学生,每个学生的数据包括学号、姓名和 X 门课的成绩,从键盘输入 N 个学生数据,要求打印出 X 门课总平均成绩,以及最高分的学生的数据(包括学号、姓名、X 门课的成绩、平均分数)。算法分析: 使用结构体数据类型来处理;因为有N个学生,而每个学生又有多个属性以及多门课程成绩如果用我们之前学习的数组来处理,各个数组相互独立,难以反映它们之间的相互内在联系。故而,我们使用结构体数组来处理该问题。每一个学生的信息用结构体来描述,包含学号、姓名、X门课的成绩、平均成绩(比较谁分数最高时用,最后输出也有要求)。N个学生的信息用一个含有N个元素的学生结构体类型的数组来存放。在本题的实际例子程序中,以2个学生,每个学生有2门课为例运行。 用for循环输入这5个学生信息,同时把每个输入的成绩加入总成绩,并计算每个学生的平均成绩,存入到该学生结构体的ave成员。算出总平均成绩并输出。 用自定义函数找出最高分学生,函数的形参接受结构体数组首地址和数组元素个数,返回类型是学生结构体指针,该指针指向最高分的学生结构体元素首地址。在该函数定义中,通过记住最高分学生的下标来记住最高分学生,最后返回的指针值应该是 (首地址+最高分学生的下标)。 根据返回的指针,输出最高分学生的数据,(包括学号、姓名、X 门课的成绩、平均分数)。算法设计: 输入N个学生的数据; 计算平均成绩,总成绩,和总平均成绩。 调用函数求得最高分学生所在的结构体元素,返回该学生结构体元素的地址。 根据返回的指针,输出最高分学生的数据。具体流程图如图6-2所示。图6-2 【案例6-2】流程图C语言程序如下:#include #define N 2#define X 2struct student int num; /*学号*/ char name10; /*姓名*/ float scoreX; /*存放X门课成绩的数组*/ float ave; /*平均成绩*/ ; /*学生结构体类型声明结束*/struct student* max(struct student*, int n);/*求最高分学生函数声明*/void main() struct student stuN; /*存放N个学生信息的结构体数组*/ struct student * p; /*结构体指针,用来接收函数返回值*/ int i,j; float sum=0,t_ave,temp=0; /*sum存放所有学生总成绩,t_ave存放总平均成绩*/ /*temp用来暂时存放每个学生的总成绩*/ printf(请输入2个学生的学号 姓名 和2门课程成绩n); for(i=0;iN;i+) scanf(%d%s,&stui.num,); for(j=0;jX;j+)scanf(%f,&stui.scorej);sum+=stui.scorej;temp+=stui.scorej; stui.ave=temp/X; temp=0; /*清空temp,为下个学生做准备*/ t_ave=sum/(N*X); for(i=0;iN;i+) printf(%d,%s,stui.num,); for(j=0;jnum,p-name); for(j=0;jscorej); printf(n他的平均成绩是 %f,p-ave); putchar(n);/*求最高分学生函数的定义*/struct student* max(struct student*p, int n)int i; float max=p-ave; int index=0; for(i=0;iavemax) max=(p+i)-ave; index=i; return(p+index);运行结果如下:请输入2个学生的学号 姓名 和2门课程成绩用户输入1 zhao 77 88 2 qian 88 99 然后按回车1,zhao,77.0 88.02,qian,88.0 99.0 总平均成绩:88.000000最高分成绩的学生是:2,qian,88.0 99.0 他的平均成绩是:93.500000程序说明: struct student int num; /*学号*/ char name10; /*姓名*/ float scoreX; /*存放X门课成绩的数组*/ float ave; /*平均成绩*/ ;声明了一个结构体类型,该类型名字取为 student ,该类型把4种不同类型的变量捆绑在一起来描述学生信息。 struct student* max(struct student*, int n);/*求最高分学生函数声明*/声明了一个自定义函数max,该函数需要返回一个最高分学生结构体的地址,这样main函数才能根据这个地址来输出该学生的其他信息。所以,返回类型是一个指针,一个学生结构体类型的指针。该函数需要接收的参数有两个,一个是结构体类型的指针,用来接收结构体数组的首地址,另外一个是整形,用来接收结构体数组的元素个数。 struct student stuN;定义student 结构体类型的一个有N个元素的数组,名字为 stu,用来存放N个学生的信息。 struct student * p; 定义student 结构体类型的一个指针,用来存放max函数返回来的结构体地址。 scanf(%d%s,&stui.num,); scanf(%f,&stui.scorej) 以上三个scanf语句,分别接收输入结构体数组中第i个成员的学号,名字和X门课程的成绩(j从0到X-1)。输入的时候用空格或者回车分开他们。 p=max(stu,N);/*求最高分函数的调用*/stu是结构体数组的名字,代表数组的首地址,把地址作为实际参数传递给形参,同时把数组的元素个数N也传递过去。max函数执行完毕之后,会返回最高分学生的结构体元素地址,我们把这个地址赋值给结构体指针p。 printf(The max score student is n%d,%s,p-num,p-name);使用指针访问结构体变量的成员,可以通过 结构指针-成员名 的形式访问6.3.2 共用体类型的使用共用体是另一种构造型数据类型,是多种变量共享一片内存空间。直观地讲,共用体可以把所在存储单元中相同的数据部分当作不同的数据类型来处理,或用不同的变量名来引用相同的数据部分。共用体常用于需要频繁进行类型转换的场合,及压缩数据字节或程序移植等方面。【案例6-3】假设一个学生的信息表中包括学号、姓名和一门课的成绩。而成绩通常又可采用两种表示方法:一种是五分制,采用的是整数形式;另一种是百分制,采用的是浮点数形式,现要求编一程序,输入一个学生的信息并显示出来。注意:输入的学生的成绩可能是五分制,也可能是百分制,根据用户提示,例如,输入类型为0代表将要输入五分制,输入类型为1代表将要输入百分制成绩。算法分析:学生信息中有几种不同类型的数据,所以用结构体。成绩只能是五分制或者百分制中的一种,但这两种数据类型不一样,所以用共用体。算法设计:定义结构体提示用户输入学生信息以及分数的类型接收用户输入的信息,根据用户输入的分数的类型,用不同的成绩格式接收语句接收成绩输入。显示学生信息具体流程图如图6-3所示。图6-3 【案例6-3】流程图C语言程序如下:#include stdio.hstruct stu_score int num; char name20; int type; /*用户输入type值为0时五分制,type值为1时百分制*/ union mixed int iscore; /*五分制*/ float fscore; /*百分制*/ score; ; /*结构体声明结束*/void main() struct stu_score stud1; printf(please input num name type:n); scanf(%d %s %d,&stud1.num,,&stud1.type); if(stud1.type=0) /*如果用户输入类型为0,表示他将采用五分制输入成绩*/ printf(please input iscoren); scanf(%d,&stud1.score.iscore); printf(num=%d name=%s tpye=%dscore=%f,stud1.num,,stud1.type,stud1.score.iscore); else if(stud1.type=1) /*如果用户输入类型为1,表示他将采用百分制输入成绩*/ printf(please input fscoren); scanf(%f,&stud1.score.fscore); printf(num=%d name=%s tpye=%d score=%d,stud1.num,,stud1.type,stud1.score.fscore); 运行结果如下:please input num name type:用户输入: 1 jack 1 然后按回车please input fscore88.5num=1 name= jack tpye=1 score88.50000程序说明: struct stu_score int num; char name20; int type;/*用户输入type值为0时五分制,type值为1时百分制*/ union mixed int iscore;/*五分制*/ float fscore;/*百分制*/ score; ;声明结构体类型,结构体类型stu_score一共有4个成员,其中最后一个成员为共用体该共用体变量score可以存放一个代表五分制成绩的整型数据到iscore,或者存放一个代表百分制成绩的浮点型数据到 fscore,但不能同时存放,每次只能存放两者中的一种。具体存放哪种,可以根据用户输入的类型type来判断,用户输入type值为0时存取五分制iscore,用户输入type值为1时存取百分制fscore。 if(stud1.type=0)/*如果用户输入类型为0,表示他将采用五分制输入成绩*/ printf(please input iscore); scanf(%d,&stud1.score.iscore); stud1.type的值是用户在scanf(%d%s%d,&stud1.num,,&stud1.type);这个语句中输入的,我们判断这个值是0还是1(这里假设用户遵循题目提示,不会输入0和1以外的数字),如果是0,则用整型的&stud1.score.iscore这个地址来存放五分制成绩。否则,用&stud1.score.fscore。6.3.3 枚举类型的使用枚举类型就是将变量可能出现的值放在一起而形成的一个整型常量的集合类型,限制在此集合内,变量只能取这个集合中的某个值。【案例6-4】假设一个学生的信息表中包括学号、姓名和一门课的成绩。而成绩通常又可采用两种表示方法:一种是五分制,采用的是整数形式;另一种是百分制,采用的是浮点数形式,现要求编一程序,输入一个学生的信息并显示出来。注意:输入的学生的成绩可能是五分制,也可能是百分制,根据用户提示,例如,输入类型为0代表将要输入五分制,输入类型为1代表将要输入百分制成绩。(同例6-3,但此次我们将应用枚举类型)算法分析:在案例6-3中,我们在结构体中定义了一个整型成员type来存放用户输入的类型。虽然解决了问题,但假如代码没有注释,读起来会有一定理解障碍,所以,我们可以应用枚举类型改写,定义1个枚举类型成员type来描述类型,改成员取值范围我们在程序中定义为wu,bai集合wu代表五分制,bai代表百分制。这样阅读起来比较顺畅。其他算法同前。C语言程序如下:#include struct stu_score int num; char name20; enum scoretypewu,baitype; /*枚举类型变量tpye*/ /*用户输入type值为0时五分制,type值为1时百分制*/ union mixed int iscore; /*五分制*/ float fscore /*百分制*/ score; ; /*结构体声明结束*/void main() struct stu_score stud1; printf(please input num name type:n); scanf(%d%s%d,&stud1.num,,&stud1.type); if(stud1.type=wu) /*如果用户输入类型为0,对应枚举值为wu,表示他将采用五分制输入成绩*/ printf(please input iscoren); scanf(%d,&stud1.score.iscore); else if(stud1.type=bai) /*如果用户输入类型为1,对应枚举值为bai,表示他将采用百分制输入成绩*/ printf(please input fscoren); scanf(%f,&stud1.score.fscore); if(stud1.type=wu)printf (%d,%s,%d,%d,stud1.num,,stud1.type,stud1.score.iscore); else if(stud1.type=bai)printf(%d,%s,%d,%f,stud1.num,,stud1.type,stud1.score.fscore);运行结果如下:please input num name type:用户输入:1 jack 0 Please input iscore:801,jack,0,80程序说明: enum scoretypewu,baitype; /*枚举类型变量tpye*/声明一个枚举类型,并定义一个枚举型变量,枚举型仅适应于取值有限的数据,取值表中的值称为枚举元素,枚举元素是常量。在C编译器中,按定义的顺序取值0、1、2、.。所以,这里的wu元素取值0,bai元素取值1。 scanf(%d%s%d,&stud1.num,,&stud1.type); if(stud1.type=wu) 这里,如果用户输入0,对应枚举值为wu,表示他将采用五分制输入成绩 但是,用户不能直接输入wu,因为scanf里的输入类型是%d,所以只能按枚举类型的实际取值0或1来输入。 比较的时候,“=”号左边是枚举类型变量,右边是枚举类型取值范围之一wu,所以没有问题,假如,写成if(stud1.type=0)也是不会出错的,但是那样就失去了我们引入枚举类型的意义了。6.3.4 简单链表的应用1. 链表的建立与遍历【案例6-5】建立有n个学生成绩的结构记录(学生有学号,成绩这两个信息),其中n由用户在程序运行中输入。算法分析:本题与例子6-1不同之处在于,6-1题中学生人数是10人,是程序运行之前就确定了的,所以可以用结构体数组来存放学生信息。而本题的学生人数是n,在程序运行之前是不确定的,而定义数组时,元素个数必须是常量,因此不能用结构体数组来处理。链表是动态地进行存储分配的一种数据结构,动态是指:需要一个存放元素,申请一个元素的存储空间。实际上,链表的每一个结点就是一个数据结构而已,只不过是每个结点都有一个可以用来存放下一个结点的地址指针。链表是由头指针和一列表结点通过指针链接而成。链表预先不必定义其结点的最大数目,在程序执行期间,可以根据需要增加或删除链表中的结点。针对本题的要求,我们可以采用链表结构来存放这n个学生的信息。形成如图6-4 所示的链表:图6-4 链表图算法设计: 设3个指针变量:head、p1、p2,它们都是用来指向struct student类型数据 申请第一个结点空间,把该空间的地址赋值给head和p2,使head和p2都指向它。 再申请另一个结点空间,把该空间的地址赋值给p1,使p1指向它,接着输入该结点的数据,并把该空间的地址赋值给p2的指针成员(该成员设计为存放下一个结点地址),使得该结点与上一结点相连,然后该空间的地址赋值给p2,让p2指向新建立的结点,也即p2指向当前链表的最后一个结点。 重复。 为尾结点的指针成员赋值NULL具体流程图如图6-5所示图6-5 【案例6-5】流程图C语言程序如下:#define LEN sizeof(struct student)/*定义代表结构体长度的宏*/#include #include struct student /*定义结构体类型*/ int num; float score; struct student *next; /*student类型的指针,存放student结构体变量地址*/ ;void main() int n,i; struct student *head=NULL, *p1, *p2; /*定义3个结构体类型指针分别用来指向链表头,新结点和未结点*/printf(please input nn); scanf(%d,&n); /*结点个数*/ head=p2=(struct student * ) malloc(LEN); /*第一个结点*/ scanf(%d%f,&p2-num,&p2-score); for(i=2;inum,&p1-score); p2-next=p1; /*与上一结点相链*/ p2=p1; /*使p2指向新结点*/ p2-next=NULL; /*尾结点的指针域置空*/程序说明: #define LEN sizeof(struct student)中的sizeof()函数,返回类型或变量长度 struct student/*定义结构体类型*/ int num; float score; struct student *next; /*student类型的指针,存放student结构体变量地址*/ ;定义结构体类型即接下来的生成的链表的每一个结点的类型。链表中每一结点一般由两大部分组成:数据域,用于存放用户需要用的实际数据,可以是一个数据项,也可以是多个数据项。指针域,用于存放和该结点相链接的下一个结点的地址。指针域是同类型的结构体指针变量。链表中最后一个尾结点因其后续无结点,该指针域不再指向其他结点,存放一个“NULL”(表示空地址)。 在这里,数据域就是int num; float score;这两个成员,指针域就是struct student *next; struct student *head=NULL, *p1, *p2; head用来指向链表头,p1用来指向新结点,p2用来指向尾结点 head=p2=(struct student * ) malloc(LEN); malloc函数在内存的动态存储区中分配一个长度为LEN空间,返回一个指向分配域起始地址的指针(基类型为void)。这里我们把返回的void用(struct student * ) 强制类型转换成链表的结点类型。因为是第一个结点,所以该结点即使头结点也是尾结点,故将地址赋值给p2和head。 for循环继续完成剩余结点的生成和链接。l p1= ( struct student*) malloc(sizeof(struct student) 申请一个新结点,把返回的地址赋值给p1,使p1指向新申请的结点。l scanf(%d%f,&p1-num,&p1-score);输入数据l p2-next=p1;p1里存放着新申请的结点的地址,那么,将p1赋值给p2的next成员,也就是使得next指针指向新申请的结点,使得新结点与原来的尾结点相连,实现将新申请的结点插入到链表尾,成为新的尾结点。l p2=p1; p2的功能是指向尾结点,所以,有了新的尾结点后,把新的尾结点的地址赋值给p2,使得p2指向新的尾结点。 p2-next=NULL;for循环结束,表示链表建立完成,整个链表的尾结点后面不会有结点了,为了可以为for循环等结构提供结束的参考,我们给链表结束的位置做一个标识,把尾结点的指针域置空即NULL。【案例6-6】设已有案例6-5建立的单向链表,编写统计链表长度的函数。算法分析:统计链表长度,只需要知道链表从哪里开始到哪里结束。然后从开始的结点起,每找到一个结点统计长度加1,然后根据该结点的next指针里的值,找到下一个结点,如此循环,直到看到最后一个结点。链表建立好之后,有一个指向头结点的指针,尾结点的标志是next成员的值为NULL。所以,我们根据得到的参数头指针,顺着next这个藤摸NULL这个瓜就可以了。具体流程图如图6-6所示。图6-6 【案例6-6】的流程图C语言程序如下:int len_link(struct student *head)/*形参head为要输出链表的头指针*/ int n=0; struct student *p; p=head; while(p!=NULL) n+;/*累计计数*/ p=p-next;/*移动指针*/ return (n);/*将n的值返回*/程序说明: int len_link(struct student *head)形参是指向链表头结点的指针,所以是struct student*类型,本函数返回值是链表长度,所以是int 型。 while(p!=NULL)p!=NULL的含义是:p所指的地址不为空。什么情况下p指的地址为空呢?情况一,链表一个结点也没有,这样,第一次判断的时候p就是空的,循环一次都不会执行。情况二,当指针指向尾结点,做了循环体内的n+;p=p-next;之后,因为尾结点的next中存放着NULL,所以此时p所指为空。p=p-next; 将p的next成员中存放的地址赋值给p,p的next成员中存放的是p的下一个结点的地址。所以,经过赋值,p中存放的是原来的结点的下一个结点的地址。也即p向后移动一个结点。2. 链表的删除【例6-7】在上例建立的链表中,删除链表中结点num域的值等于输入值del_num的结点。编写函数struct student *delete(struct student *head,int num)实现。算法分析:根据条件删除一个已知链表中的某个结点的算法是:先查找到该结点,然后把该结点的指针域赋给其前趋结点的指针域或链表头指针head。 删除首结点:使p1指向第一个结点,用以下语句实现删除首结点操作:p1=head;head=p1-next;如图6-7所示。图6-7 删除首节点然后再释放p1结点空间; 删除其他结点:删除链表的中间结点通过将下一结点和尾结点地址赋给前一结点地址来实现,也即将要删除的p1结点的后继地址,放入前一结点p2的地址域(p2-next=p1-next;),同时释放p1结点空间;如图6-8所示。图6-8 删除其它节点C语言程序如下:struct student *delete(struct student *head,int num) struct student *p1,*p2;if (head=NULL) printf(list null!n); /*空链表*/else p1=head; /*从头结点开始*/while(p1!=NULL & p1-num != num) /*while循环查找删除结点*/ p2=p1; p1=p1-next; /*后移一个结点*/ if(p1-num = num) /*找到了*/ if(p1 = head) head=p1-next; /*删除头结点*/ else p2-next=p1-next; /*删除中间结点*/ free(p1); /*释放p1结点空间*/ else printf(%d not been found!n,num); return(head); /*返回链表的首地址指针*/程序说明: struct student *delete(struct student *head,int num)函数的两个形参,一个是链表结点类型的指针head,用来接收待处理的链表的首地址,另一个是整型变量num,用来接收用户想要删除的结点的num域的值。函数的返回类型是链表结点类型的指针,返回的值是经过处理以后的链表的首地址。 while(p1!=NULL & p1-num != num) /*while循环查找删除结点*/ p2=p1; p1=p1-next; /*后移一个结点*/这个查找过程中,循环体的过程是:首先,p2=p1把当前结点的指针p1中的地址赋值给p2,于是p2指向当前比较过的这个结点;然后,p1=p1-next,把当前比较过的结点的next成员中的地址赋值给p1,也即p1指向了下一个结点。所以,这两步执行完后,p1指向本次比较过的结点的下一个结点,p2指向p1前一个结点,也即本次比较过的结点,形成两个指针一前一后的状况。 free(p1)其作用是释放由p1指向的内存区,使这部分内存区能被其他变量使用。3. 链表的插入【案例6-8】编写函数,有一个已经按成绩排序好的链表,链表头指针为head。在该链表的合适位置插入stud结点,使得该链表仍然有序,并返回新链表的表头。算法分析:在一个有序的链表中插入某个结点的算法是:先查找到该结点,然后根据以下不同的情况插入: 原链表为空表即head=NULL时,用以下语句实现插入操作:head=p0;p0-next=NULL;p0是该链表唯一一个结点 在头结点之前插入若p1=head,表示插入结点在头结点之前。用以下语句实现插入操作:head=p0;p0-next=p1 在头结点之后,尾节点之前插入,即中间插入当p1!=head时,表示在头结点之后,尾节点之前(中间结点)插入结点,用以下语句实现插入操作:p2-next=p0; p0-next=p1 尾节点之后插入当p0-scorep1-score时,表示在尾节点之后插入结点,用以下语句实现插入操作:p1-next=p0;p0-next=NULL C语言程序如下:struct student *insert(struct student *head,struct student *stud) struct student *p0,*p1,*p2; p1=head; p0=stud; /*p0指向待插入结点*/ if(head=NULL) /*原链表是空表*/ head=p0;p0-next=NULL; else /*while循环查找待插入的位置*/ while(p0-score p1-score) & (p1-next!=NULL) p2=p1; p1=p1-next; /*后移一个结点*/if( p0-score score) /*找到了位置,在p1之前*/ if(p1= head) /*在表头结点插入*/ head=p0; p0-next=p1; else /*在中间结点插入*/ p2-next=p0; p0-next=p1; else /*在尾结点之后插入*/ p1-next=p0; p0-next=NULL; return(head); 程序说明: struct student *insert(struct student *head,struct student *stud)函数的两个形参,一个是链表结点类型的指针head,用来接收待处理的链表的首地址,另一个是链表结点类型的指针stu,用来接收用户想要插入的结点的地址。函数的返回类型是链表结点类型的指针,返回的值是经过处理以后的链表的首地址。 if(p1= head)/*在表头结点插入*/ head=p0; p0-next=p1; head=p0是把新结点的地址赋值给head指针,使得该结点成为新的头结点。然后,p0-next=p1,把p1的地址赋值给p0结点的next成员,使得p1所指的结点(原来的头结点)成为新的头结点的后续结点。 else /*在中间结点插入*/ p2-next=p0; p0-next=p1; 这种情况是p0插在p2和p1之间。p2在前,p1在后。只须把p2的next指针成员赋值为p0,p0的next指针成员赋值为p1。 else /*在尾结点之后插入*/ p1-next=p0; p0-next=NULL; 这种情况和上一种情况的区别是,新插入的结点之后没有后续结点了。所以,新插入的结点的next指针成员需要置为NULL。6.4 相关理论知识6.4.1 结构体1. 结构体的声明定义结构体类型的一般形式:struct 结构体名 结构成员1; 结构成员2; 结构成员n; 其中,struct为结构体定义的关键字,不能省略。结构体名由用户给定,即是定义的结构体类型名。用两个花括号括住的内容是该结构体中的各个成员,每个成员又有自己的数据类型,它们可以是整型、实型、字符型、指针或结构类型等,它们都应进行类型说明。 有关结构体的几点说明:结构体类型的定义只是说明了一种结构体的组织形式,在编译时并不为它分配存储空间。只是在定义结构体类型变量后,才为变量按照其组织形式分配内存空间。结构体的成员可以是简单变量、数组、指针,还可以是另一个已定义的结构体或共用体变量。当定义一个结构体的成员又是一个结构体类型,这称为结构体的嵌套定义。struct date int year; int month; int day; ;struct student int num; char name20; char sex; struct date birthday; float score; ; 结构体定义可以在函数内部,也可在函数外部。在函数内部定义的结构体,只有在函数内部使用,在函数外部定义的结构体,从定义点起到源文件尾之间的所有函数都可使用。结构体成员的名字可以同程序中的其他变量名相同,两者的意义不同,不会相混。2. 结构体变量的定义定义结构
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年广告策划师资格认定考试试卷及答案解析
- 2025年电子音响工程师技术水平测验试卷及答案解析
- 2025年宠物行为学导盲犬面试题库
- 课件与人工智能结合案例
- 课件《牙齿的秘密》
- 2025年慈善募捐专员笔试模拟题
- 2025年心理矫治岗位笔试模拟试卷
- 2025年AR技术中级工程师模拟题集锦
- 2025年乡村振兴专干招聘考试重点题库解析
- 2025年社保待遇核算竞聘面试模拟题
- 2025年山西省中考语文试卷真题(含答案)
- 心理健康教育:耐挫能力的培养
- 疼痛评估表课件
- 我这样做老师
- 垃圾焚烧发电项目电气安装与调试施工方案
- 枣庄市专业技术人员继续教育公需科目2021年度补考题库及卫生专科课题库
- 高考作文答题卡(作文)
- GB/T 3921-2008纺织品色牢度试验耐皂洗色牢度
- GB/T 18114.11-2010稀土精矿化学分析方法第11部分:氟量的测定EDTA滴定法
- DB3302T 1079-2018 管线探测技术规程
- 湖南省长沙市四大名校小升初数学真题
评论
0/150
提交评论