C语言超级奥妙-结构体与链表 联系客服

发布时间 : 星期日 文章C语言超级奥妙-结构体与链表更新完毕开始阅读4c2971c708a1284ac85043fb

第10章

结构体与共用体

21

(2)把一个整数进行强制类型转换后再赋值给枚举变量,如enum color y=(enum color)0。

【注意】① 枚举常量是一个标识符,可在定义枚举类型时为其赋值,但不能在程序中为其

赋值。如对于定义enum{ mon,tue,wed,thr,fri }d,赋值语句mon=1是非法的。 ② 枚举常量既非字符常量,也非字符串常量,使用时不可加单引号或双引号。

2.枚举变量的输出

通常使用switch语句或if语句输出枚举变量的值。如:

enum workday { mon,tue,wed,thr,fri };

enum workday d=mon; switch(d) { case mon:printf(\ case tue:printf(\ case wed:printf(\ case thr:printf(\ case fri:printf(\ default:printf(\}

【说明】枚举常量不是字符串常量,不能用“%s”的格式输出,如程序片段不会输出mon:

enum{ mon,tue,wed,thr,fri }d=mon;

printf(\

【思考】试用if语句输出枚举变量的值。 10.4.4 枚举应用举例

枚举类型数据相互之间以及枚举类型数据与整型数据之间可以进行比较运算或算术运算。对于枚举类型数据来说,参与运算的实际是枚举常量的值,且运算结果为整型数据。因此,将运算结果赋值给一个枚举变量前要进行强制类型转换。例如以下程序片段的最后一行:

enum workday { mon,tue,wed,thr,fri }d1=mon,d2=tue;

d1=(enum workday)(d1+d2);

读入整数nfor(i=2;i<=n;i++)Yd=(enum weekday)(d+1)Ywangwu值班d!=sund=mond

lisi、wangwu轮流值班,每人值一天,输入整数n,求第n天是周几,何人值班?假设假期第一天是周二,且由zhangsan值班。

程序的算法描述如图10.25所示,代码如下:

#include void main()

NYonduty=zhangsonduty=(workaner)(onduty+1)输出d的值d

{ }

第10章

结构体与共用体

22

enum weekday{mon,tue,wed,thu,fri,sat,sun}d=tue; enum worker{zhangsan,lisi,wangwu}onduty=zhangsan; int i,n;

printf(\scanf(\for(i=2;i<=n;i++) { if(d!=sun)/*前一天为周日*/ d=(enum weekday)(d+1); else/*前一天非周日*/ d=mon; if(d

switch(d)/*输出今天是周几*/ {

case mon:printf(\case tue:printf(\case wed:printf(\case thu:printf(\case fri:printf(\case sat:printf(\case sun:printf(\default:break; }

if(d

else /*今天是周末,无人值班*/ printf(\

10.5 应 用 举 例

本节结合实例说明如何用结构体与链表解决学生成绩管理系统中的一些问题。 例10.14 找出各门课平均分在85以上的同学,并输出这

些同学的信息。

程序中创建链表子函数的算法描述如图10.14所示,主

创建并初始化学生成绩链表p=headwhile(p!=NULL)计算当前结点各门课成绩之和计算当前结点的平均成绩是否在85以上YN输出该结点信息p2指向下一结点 图10.26 例10.14主函数N-S图

第10章

结构体与共用体

23

函数的算法描述如图10.26所示,代码如下:

#include #include

#define M 5 /*学生数*/ #define N 3 /*课程数*/ struct student { long num; char name[20]; float score[N]; struct student *next; };

/*创建链表子函数*/

struct student *create(int n) { struct student *head=NULL,*p1,*p2; int i,j; for(i=1;i<=n;i++)/*逐个创建结点并输入相关数据*/ { p1=(struct student *)malloc(sizeof(struct student)); printf(\请输入第%d个学生的学号、姓名及各门课考试成绩:\\n\ scanf(\ for(j=0;jnext=NULL; if(i==1) head=p1; else p2->next=p1; p2=p1; } return(head); }

void main() { struct student *head=NULL,*p; int i; float sum,aver; head=create(M); p=head; while(p!=NULL)/*用指针p遍历链表各个结点*/ { sum=0; for(i=0;iscore[i]; aver=sum/N; if(aver-85>-1e-6) { printf(\学号:%ld 姓名:%s \ for(i=0;inext; } }

【思考】能否用“aver>=85”表示平均分aver的值在85以上?

第10章

结构体与共用体

24

例10.15 假设N个同学已按学号大小顺序排成一圈,现要从中选一人参加比赛。规则是:

从第一个人开始报数,报到M的同学就退出圈子,再从他的下一个同学重新开始从1到M的报数,如此进行下去,最后留下一个同学去参加比赛,问这位同学是几号。

算法设计思想:用单向循环链表(令单向链表的最后一个结点的指针指向头结点,即形成单向循环链表)表示多名同学围成的圈。从头结点开始,每数到M就删除一个结点,之后令头指针指向所删除结点的下一个结点;之后,从新的头结点开始重新报数,直到链表只剩下一个结点。

单向循环链表创建子函数的算法描述如图10.27所示,主函数的算法描述如图10.28所示,代码如下:

for(i=1;i<=n;i++)开辟新结点,令p1指向它输入学生信息,指针域置空Y是否首结点N创建含N个结点的单向循环链表for(len=N;len>1;len--)令p指向头结点令p指向第M-1个结点删除第M个结点head指向删除结点的后续结点输出最后留下的同学的学号头指针指向首结点新结点与前一结点链接p2指向新结点尾结点与头结点链接返回head

图10.27 单向循环链表的建立 图 10.28 例10.15主函数N-S图

#include #include #define N 8 #define M 3 struct student { long num; struct student *next; };

/*创建单向循环链表子函数*/

struct student *create(int n) { struct student *head=NULL,*p1,*p2; int i; for(i=1;i<=n;i++)/*逐个创建结点并输入相关数据*/ { p1=(struct student *)malloc(sizeof(struct student)); printf(\请输入第%d个学生的学号:\\n\ scanf(\ p1->next=NULL; if(i==1) head=p1; else p2->next=p1; p2=p1; } p1->next=head; return(head); }

void main() { struct student *head=NULL,*p; int len,order; head=create(N); for(len=N;len>1;len--)