C程序设计(谭浩强)第五版课后题答案 第九章
1.定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。
#include <stdio.h> struct Date{ int year; int month; int day; }; int main() { struct Date date; int i=0,no=0; int Month[12]={31,28,31,30,31,30,31,31,30,31,30,31}; printf("请输入日期(年、月、日):"); scanf("%d %d %d",&date.year,&date.month,&date.day); no+=date.day; for(i=0;i<date.month-1;i++) no+=Month[i]; if(date.year%4==0 && date.year%100!=0 || date.year%400==0) no+=1; printf("%d月%d日是%d年的第%d天!\n",date.month,date.day,date.year,no); return 0; }
2.写一个函数days,实现第1 题的计算。由主函数将年、月、日传递给days函数,计算后将日子数传回主函数输出。
#include <stdio.h> struct Date{ int year; int month; int day; }; int main() { struct Date date; int i=0,no; int days(struct Date date); printf("请输入日期(年、月、日):"); scanf("%d %d %d",&date.year,&date.month,&date.day); no=days(date); printf("%d月%d日是%d年的第%d天!\n",date.month,date.day,date.year,no); return 0; } int days(struct Date date) { int i,no=0; int Month[12]={31,28,31,30,31,30,31,31,30,31,30,31}; no+=date.day; for(i=0;i<date.month-1;i++) no+=Month[i]; if(date.year%4==0 && date.year%100!=0 || date.year%400==0) no+=1; return no; }
3.编写一个函数print,打印一个学生的成绩数组,该数组中有5个学生的数据记录,每个记录包括num,name,score[3],用主函数输人这些记录,用print函数输出这些记录。
#include <stdio.h> #define M 20 struct student{ int num; char name[M]; int score[3]; }; int main() { int i; struct student stu[5]; void myprint(struct student stu[5]); printf("请按以下格式依次输入5名学生的信息:\n"); printf("num name score1 score2 score3\n"); for(i=0;i<5;i++) scanf("%d %s %d %d %d",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]); myprint(stu); return 0; } void myprint(struct student stu[5]) { int i; printf("num name score1 score2 score3\n"); for(i=0;i<5;i++) printf("%3d %3s %3d %3d %3d\n",stu[i].num,stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2]); }
4.在第3题的基础上,编写一个函数input,用来输人5个学生的数据记录。
#include <stdio.h> #define M 20 struct student{ int num; char name[M]; int score[3]; }; int main() { struct student stu[5]; void myprint(struct student stu[5]); void input(struct student stu[5]); input(stu); myprint(stu); return 0; } void myprint(struct student stu[5]) { int i; printf("num name score1 score2 score3\n"); for(i=0;i<5;i++) printf("%3d %3s %3d %3d %3d\n",stu[i].num,stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2]); } void input(struct student stu[5]) { int i; printf("请按以下格式依次输入5名学生的信息:\n"); printf("num name score1 score2 score3\n"); for(i=0;i<5;i++) scanf("%d %s %d %d %d",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]); }
5.有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩,从键盘输人10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。
#include <stdio.h> #define M 10 struct student{ int num; char name[20]; int score[3]; }; int main() { struct student stu[M]; void myprint(struct student stu[M]); void input(struct student stu[M]); void max_aver(struct student stu[M]); input(stu); myprint(stu); max_aver(stu); return 0; } void myprint(struct student stu[M]) { int i; printf("num name score1 score2 score3\n"); for(i=0;i<M;i++) printf("%3d %3s %3d %3d %3d\n",stu[i].num,stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2]); } void input(struct student stu[M]) { int i; printf("请按以下格式依次输入%d名学生的信息:\n",M); printf("num name score1 score2 score3\n"); for(i=0;i<M;i++) scanf("%d %s %d %d %d",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]); } void max_aver(struct student stu[M]) { int i,j,id,max; float sum; for(i=0;i<3;i++) { sum=0; max=0; for(j=0;j<M;j++) { sum+=stu[j].score[i]; if(max<stu[j].score[i]) { max=stu[j].score[i]; id=j; } } printf("第%d门课的平均分是%.2f\n",i+1,sum/M); printf("第%d门课的最高分是%d\n",i+1,max); printf("这名学生的信息如下:\n"); printf("num name score1 score2 score3\n"); printf("%3d %3s %3d %3d %3d\n",stu[id].num,stu[id].name,stu[id].score[0],stu[id].score[1],stu[id].score[2]); printf("\n"); } }
6.13个人围成一圈,从第1个人开始顺序报号1,2,3。凡报到3者退出圈子。找出最后留在圈子中的人原来的序号。要求用链表实现。
解题思路:
创建一个环形链表,给链表中的每一个节点从1~13编号,然后开始淘汰过程,对于淘汰的节点,序号置为0,淘汰完成之后,找到序号不为0的即为最后留下的。
#include <stdio.h> #define M 13 struct people{ int num; struct people *next; }; int main() { int i,count; struct people peo[M],*head; head=peo; for(i=0;i<M;i++) { head->num =i+1; head->next=&peo[i+1]; head=head->next; } peo[M-1].next=peo; //最后一个元素指向第一个元素 i=0; count=M; head=peo; while(count>1) { i++; if(head->num==0) { head=head->next; continue; } if(i==3) { printf("%d号被淘汰\n",head->num); head->num=0; count--; i=0; } head=head->next; } printf("\n"); while(head->num==0) { head=head->next; if(head->num!=0) printf("最后留下的是%d号\n",head->num); } return 0; }
7.在第9章例9.9和例9.10的基础上,写一个函数del,用来删除动态链表中指定的节点
解题思路:
首先创建一个带头的单链表,然后让用户输入需要删除的节点,调用del函数,找到需要删除的节点,把待删除节点的前驱和后继重新链接。
#include <stdio.h> #include<stdlib.h> #define LEN sizeof(struct LNode) struct LNode{ long num; struct LNode *next; }; int n; int main() { long m; struct LNode *pt; struct LNode * creat(); void print(struct LNode * head); void del(struct LNode * head,long m); printf("建立链表(输入0停止建立)\n"); pt=creat(); print(pt); printf("要删除的节点是: \n"); scanf("%ld",&m); del(pt,m); print(pt); return 0; } struct LNode * creat() { struct LNode *head,*p1,*p2; head=(struct LNode *)malloc(LEN); n=0; p1=p2=(struct LNode *)malloc(LEN); printf("请输入第1个数据:"); scanf("%ld",&p1->num); printf("\n"); head=NULL; while(p1->num!=0) { n=n+1; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct LNode *)malloc(LEN); printf("请输入第%d个数据:",n+1); scanf("%ld",&p1->num); printf("\n"); } p2->next=NULL; return(head); } void print(struct LNode * head) { struct LNode *p; printf("链表的数据如下:\n"); p=head; if(head!=NULL) do { printf("%ld ",p->num); p=p->next; }while(p!=NULL); printf("\n"); } void del(struct LNode * head,long m) { struct LNode *p1,*p2; if(head==NULL) printf("list null!\n"); p1=head; while(p1->num!=m && p1->next!=NULL) { p2=p1; p1=p1->next; } if(p1->num==m) { if(p1==head) head=p1->next; else p2->next=p1->next; n=n-1; } else printf("%ld 未找到\n",m); }
8.写一个函数insert,用来向一个动态链表插入结点
#include <stdio.h> #include<stdlib.h> #define LEN sizeof(struct LNode) struct LNode{ long num; struct LNode *next; }; int n; int main() { int insert_id,insert0; struct LNode * creat(),*pt; void print(struct LNode * head); void insert(struct LNode * head,int insert_id,int insert0); printf("建立链表(输入0停止建立)\n"); pt=creat(); print(pt); printf("请输入要插入的位置以及数据:"); scanf("%d %d",&insert_id,&insert0); insert(pt,insert_id,insert0); print(pt); return 0; } struct LNode * creat() { struct LNode *head,*p1,*p2; head=(struct LNode *)malloc(LEN); n=0; p1=p2=(struct LNode *)malloc(LEN); printf("请输入第1个数据:"); scanf("%ld",&p1->num); printf("\n"); head=NULL; while(p1->num!=0) { n=n+1; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct LNode *)malloc(LEN); printf("请输入第%d个数据:",n+1); scanf("%ld",&p1->num); printf("\n"); } p2->next=NULL; return(head); } void print(struct LNode * head) { struct LNode *p; printf("链表的数据如下:\n"); p=head; if(head!=NULL) do { printf("%ld ",p->num); p=p->next; }while(p!=NULL); printf("\n"); } void insert(struct LNode * head,int insert_id,int insert0) { struct LNode *p1,*p2; p1=head; insert_id-=1; while(--insert_id) { p1=p1->next; } p2=(struct LNode *)malloc(LEN); p2->num=insert0; p2->next=p1->next; p1->next=p2; }
9.综合本章例9.9(建立链表的函数creat)、例9.10(输出链表的函数print)和本章习题第7题(删除链表中结点的函数del)、第8题(插入结点的函数insert),再编写一个主函数,先后调用这些函数。用以上5个函数组成一个程序,实现链表的建立、输出、删除和插入,在主函数中指定需要删除和插人的结点的数据。
#include <stdio.h> #include<stdlib.h> #define LEN sizeof(struct LNode) struct LNode{ long num; struct LNode *next; }; int n; int main() { char c; int insert_id,insert0,m,flag=1; struct LNode * creat(),*pt; void print(struct LNode * head); void insert(struct LNode * head,int insert_id,int insert0); void del(struct LNode * head,long m); pt=creat(); print(pt); while(flag==1) { printf("插入数据(1) 删除数据(2) 结束(3):"); getchar(); scanf("%c",&c); if(c=='1') { printf("请输入要插入的位置以及数据:"); scanf("%d %d",&insert_id,&insert0); insert(pt,insert_id,insert0); print(pt); } if(c=='2') { printf("请输入要删除的数据:"); scanf("%ld",&m); del(pt,m); print(pt); } if(c=='3') flag=0; } print(pt); return 0; } struct LNode * creat() { struct LNode *head,*p1,*p2; head=(struct LNode *)malloc(LEN); n=0; p1=p2=(struct LNode *)malloc(LEN); printf("请输入第1个数据:"); scanf("%ld",&p1->num); printf("\n"); head=NULL; while(p1->num!=0) { n=n+1; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct LNode *)malloc(LEN); printf("请输入第%d个数据:",n+1); scanf("%ld",&p1->num); printf("\n"); } p2->next=NULL; return(head); } void print(struct LNode * head) { struct LNode *p; printf("链表的数据如下:\n"); p=head; if(head!=NULL) do { printf("%ld ",p->num); p=p->next; }while(p!=NULL); printf("\n"); } void insert(struct LNode * head,int insert_id,int insert0) { struct LNode *p1,*p2; p1=head; insert_id-=1; while(--insert_id) { p1=p1->next; } p2=(struct LNode *)malloc(LEN); p2->num=insert0; p2->next=p1->next; p1->next=p2; } void del(struct LNode * head,long m) { struct LNode *p1,*p2; if(head==NULL) printf("list null!\n"); p1=head; while(p1->num!=m && p1->next!=NULL) { p2=p1; p1=p1->next; } if(p1->num==m) { if(p1==head) head=p1->next; else p2->next=p1->next; n=n-1; } else printf("%ld 未找到\n",m); }
10.已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并, 按学号升序排列。
#include <stdio.h> #include<stdlib.h> #define LEN sizeof(struct student) struct student{ int num; double grade; struct student *next; }; int main() { int i; struct student a[4]={{1,99},{2,98.5},{5,99.1},{6,99.2}}; struct student b[5]={{3,99.3},{4,99.4},{9,99.6},{7,99.7},{8,99.8}}; struct student *Merge( struct student *L1,struct student *L2 ); struct student *head1,*head2,*p1,*p2,*p; head1=a; head2=b; printf("a链表的数据如下:\n"); p1=head1; for(i=1;i<=4;i++) { if(i<4) p1->next=a+i; else p1->next=NULL; printf("%d %.2lf\n",p1->num,p1->grade); if(i<4) p1=p1->next; } printf("b链表的数据如下:\n"); p2=head2; for(i=1;i<=5;i++) { if(i<5) p2->next=b+i; else p2->next=NULL; printf("%d %.2lf\n",p2->num,p2->grade); if(i<5) p2=p2->next; } p=Merge(head1,head2); printf("排序后的链表如下:\n"); while(p!=NULL) { printf("%4d %7f \n",p->num,p->grade); p=p->next; } return 0; } struct student *Merge(struct student *a,struct student *b) { int num; double grade; struct student *head,*pre; head=a; while(a->next!=NULL) a=a->next; a->next=b; pre=head; while(pre->next!=NULL) { a=pre->next; while(a!=NULL) { if(pre->num > a->num) { num=pre->num; grade=pre->grade; pre->num=a->num; pre->grade=a->grade; a->num=num; a->grade=grade; } a=a->next; } pre=pre->next; } return head; }
11.有两个链表a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。
解题思路:
对于b链表中的每一个节点,都从a链表的表头开始查找,如果可以找到,直接删除,如果找不到,继续从a链表表头找下一个b的节点。
#include <stdio.h> #include <string.h> #define LA 4 #define LB 5 struct student{ int num; char name[8]; struct student *next; } a[LA],b[LB]; int main() { struct student a[LA]={{101,"Wang"},{102,"Li"},{105,"Zhang"},{106,"Wei"}}; struct student b[LB]={{103,"Zhang"},{104,"Ma"},{105,"Chen"},{107,"Guo"},{108,"lui"}}; int i; struct student *p,*p1,*p2,*head1,*head2; head1=a; head2=b; printf(" list A: \n"); p1=head1; for(i=1;i<=LA;i++) { if(i<LA) p1->next=a+i; else p1->next=NULL; printf("%4d%8s\n",p1->num,p1->name); if(i<LA) p1=p1->next; } printf("\n list B:\n"); p2=head2; for(i=1;i<=LB;i++) { if(i<LB) p2->next=b+i; else p2->next=NULL; printf("%4d%8s\n",p2->num,p2->name); if(i<LB) p2=p2->next; } p1=head1; while(p1!=NULL) { p2=head2; while((p1->num != p2->num) && (p2->next!=NULL)) //p1与p2的值依次比较 p2=p2->next; if(p1->num == p2->num) //p1=p2时 { if(p1==head1) head1=p1->next; else { p->next=p1->next; p1=p1->next; } } else //比较到结束,p1与p2没有相同的 { p=p1; p1=p1->next; } } printf("\nresult:\n"); p1=head1; while(p1!=NULL) { printf("%4d %7s \n",p1->num,p1->name); p1=p1->next; } return 0; }
12.建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。
#include <stdio.h> #include<stdlib.h> #define LEN sizeof(struct student) struct student{ int num; char name[20]; char sex[6]; int age; struct student *next; }; int n; int main() { int years; struct student * creat(),*pt; void print(struct student * head); void del(struct student * head,int delage); pt=creat(); print(pt); printf("请输入要删除的年龄:"); scanf("%d",&years); del(pt,years); print(pt); return 0; } struct student * creat() { struct student *head,*p1,*p2; head=(struct student *)malloc(LEN); n=0; p1=p2=(struct student *)malloc(LEN); printf("请按以下格式输入每名学生的信息(输入0 停止录入):\n"); printf("num name sex age"); printf("请输入第1个学生信息:"); scanf("%d%s%s%d",&p1->num,p1->name,p1->sex,&p1->age); printf("\n"); head=NULL; while(p1->num!=0) { n=n+1; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct student *)malloc(LEN); printf("请输入第%d个同学信息:",n+1); scanf("%d%s%s%d",&p1->num,p1->name,p1->sex,&p1->age); printf("\n"); } p2->next=NULL; return(head); } void print(struct student * head) { struct student *p; printf("链表的数据如下:\n"); p=head; if(head!=NULL) do { printf("%3d %3s %3s %3d\n",p->num,p->name,p->sex,p->age); p=p->next; }while(p!=NULL); printf("\n"); } void del(struct student * head,int delage) { struct student *p1,*p2; if(head==NULL) printf("list null!\n"); p1=head; while(p1->age!=delage && p1->next!=NULL) { p2=p1; p1=p1->next; } if(p1->age==delage) { if(p1==head) head=p1->next; else p2->next=p1->next; } else printf("%d 未找到\n",delage); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探