谭浩强【C语言程序设计】第九章习题详解

2024-02-18 23:28

本文主要是介绍谭浩强【C语言程序设计】第九章习题详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 


1.定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。

#include <stdio.h>struct date
{int year;int month;int day;
}d;int main()
{int day[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };printf("请输入年 月 日:\n");scanf("%d%d%d", &d.year, &d.month, &d.day);int days = 0;for (int i = 1; i < d.month; i++){days += day[i];}days += d.day;if (d.year % 4 == 0 && d.year % 100 != 0 || d.year % 400 == 0){if (d.month > 2){days++;}}printf("该日在%d年%d月%d日是第%d天。\n", d.year, d.month, d.day, days);return 0;
}

2.写一个函数days,实现第1题的计算。由主函数将年、月、日传递给 days函数,计算后将日子数传回主函数输出。

#include <stdio.h>struct date
{int year;int month;int day;
}d;int days(int year, int month, int day)
{int day_tab[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };int day_sum = 0;for (int i = 1; i < d.month; i++){day_sum += day_tab[i];}day_sum += d.day;if (d.year % 4 == 0 && d.year % 100 != 0 || d.year % 400 == 0){if (d.month > 2){day_sum++;}}return day_sum;
}int main()
{printf("请输入年 月 日:\n");scanf("%d%d%d", &d.year, &d.month, &d.day);int day_sum = days(d.year, d.month, d.day);printf("该日在%d年%d月%d日是第%d天。\n", d.year, d.month, d.day, day_sum);return 0;
}

3.编写一个函数 print,打印一个学生的成绩数组,该数组中有5个学生的数据记录,每个记录包括 num, name, score[3],用主函数输入这些记录,用 print函数输出这些记录。

#include <stdio.h>
#define N 5struct student
{char num[6];char name[8];int score[3];
}stu[N];void print(struct student stu[6])
{printf("\n num   name   score1  score2  score3\n");for (int i = 0; i < N; i++){printf("%4s%6s", stu[i].num, stu[i].name);for (int j = 0; j < 3; j++){printf("%8d", stu[i].score[j]);}printf("\n");}}int main()
{for (int i = 0; i < N; i++){printf("请输入第%d个学生的的成绩:>\n", i + 1);printf("num:");scanf("%s", stu[i].num);printf("name:");scanf("%s", stu[i].name);for (int j = 0; j < 3; j++){printf("score %d:", j + 1);scanf("%d", &stu[i].score[j]);}printf("\n");}print(stu);return 0;
}

4.在第3题的基础上,编写一个函数 input,用来输入5个学生的数据记录。

#include <stdio.h>
#define N 5struct student
{char num[6];char name[8];int score[3];
}stu[N];void print(struct student stu[6])
{printf("\n num   name   score1  score2  score3\n");for (int i = 0; i < N; i++){printf("%4s%6s", stu[i].num, stu[i].name);for (int j = 0; j < 3; j++){printf("%8d", stu[i].score[j]);}printf("\n");}}void input(struct student stu[])
{for (int i = 0; i < N; i++){printf("请输入第%d个学生的的成绩:>\n", i + 1);printf("num:");scanf("%s", stu[i].num);printf("name:");scanf("%s", stu[i].name);for (int j = 0; j < 3; j++){printf("score %d:", j + 1);scanf("%d", &stu[i].score[j]);}printf("\n");}
}int main()
{input(stu);print(stu);return 0;
}

5.有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩,从键盘输入10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。

#include <stdio.h>
#define N 3struct student
{char num[6];char name[8];float score[3];float avg;
}stu[N];int main()
{for (int i = 0; i < N; i++){printf("请输入第%d个学生的的数据:>\n", i + 1);printf("num:");scanf("%s", stu[i].num);printf("name:");scanf("%s", stu[i].name);for (int j = 0; j < 3; j++){printf("score %d:", j + 1);scanf("%f", &stu[i].score[j]);}}//计算float average = 0, max = 0;int maxi = 0;float sum = 0;for (int i = 0; i < N; i++){sum = 0;for (int j = 0; j < 3; j++){sum += stu[i].score[j];//计算第i个学生总分}stu[i].avg = sum / 3.0;//计算第i个学生平均分average += stu[i].avg;if (sum > max)//找分数最高者{max = sum;maxi = i;//将此学生的下标保存在maxi}}average /= N;//计算总平均分数printf("\n num  name  score1 score2 score3  average\n");for (int i = 0; i < N; i++){printf("%3.2s%6.2s", stu[i].num, stu[i].name);for (int j = 0; j < 3; j++){printf("%8.2f", stu[i].score[j]);}printf("%8.2f\n", stu[i].avg);}printf("\naverage=%5.2f\n", average);printf("最高成绩是:student %s, %s\n", stu[maxi].num, stu[maxi].name);printf("他的成绩是:%6.2f,%6.2f,%6.2f,average:%5.2f\n", stu[maxi].score[0], stu[maxi].score[1], stu[maxi].score[2], stu[maxi].avg);return 0;
}

6.13个人围成一圈,从第1个人开始顺序报号1,2,3。凡报到3者退出圈子。找出最后留在圈子中的人原来的序号。要求用链表实现。

#include <stdio.h>
#define NUM 13//定义节点
typedef struct people
{int num;struct people* next;
}people;int main()
{//定义包含13个人的数据people arr[NUM];//建立环状链表people* head = arr;for (int i = 0; i < NUM; i++){head->num = i + 1;head->next = &arr[i + 1];head = head->next;}//构成环状链表arr[NUM - 1].next = arr;//开始报数int count = NUM;//从1开始报数int i = 1;head = arr;while (count > 1){//1.判断是否已经退出if (head->next == 0){//跳过此人head = head->next;continue;}if (i == 3){//当前此人需要退出printf("第%d个人退出\n", head->num);head->num = 0;count--;}//继续报号i++;head = head->next;//判断报号是否大于3if (i > 3){i = 1;}}//找出编号不为0的人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,用来删除动态链表中指定的结点。

#include <stdio.h>
#include <stdlib.h>typedef struct node
{int num;struct node* next;
}node;//创建链表:创建一个含有n个节点的链表,返回头节点的指针
node* creat(int n)
{//创建一个头节点node* head = (node*)malloc(sizeof(node));head->num = 0;head->next = NULL;node* p = head;//创建数据为1~n的节点for (int i = 1; i <= n; i++){node* newNode = (node*)malloc(sizeof(node));newNode->num = i;newNode->next = NULL;p->next = newNode;p = p->next;}return head;
}//打印链表数据
void printNode(node* head)
{//第一个数据为head->nextnode* p = head->next;while (p != NULL){printf("node %d\n", p->num);p = p->next;}
}void del(node* head, int val)
{node* prev = head;node* p = head;//遍历链表,找到需要删除的节点while (p != NULL){if (p->num == val){prev->next = p->next;free(p);break;}else{prev = p;p = p->next;}}
}int main()
{node* head = creat(10);int n;printf("当前链表的所有节点:\n");printNode(head);printf("请输入需要删除的节点编号:\n");scanf("%d", &n);del(head, n);//删除之后链表的节点printf("删除之后链表的节点:\n");printNode(head);return 0;
}

8. 写一个函数 insert,用来向一个动态链表插入结点。

#include <stdio.h>
#include <stdlib.h>typedef struct node
{int num;struct node* next;
}node;void insert(node* p, int n)
{//创建节点node* newNode = (node*)malloc(sizeof(node));newNode->num = n;//链接newNode->next = p->next;p->next = newNode;
}node* creat(int n)
{//创建含有n个有效数据的节点//创建一个带头的链表node* head = (node*)malloc(sizeof(node));head->num = 0;head->next = NULL;node* p = head;//创建有效数据的节点for (int i = 1; i <= n; i++){node* newNode = (node*)malloc(sizeof(node));newNode->num = i;newNode->next = NULL;p->next = newNode;p = p->next;}return head;
}void printNode(node* head)
{//从第一个有效数据开始打印node* p = head->next;while (p != NULL){printf("node %d\n", p->num);p = p->next;}
}int main()
{int n;node* head = creat(10);printf("未插入数据之前的原始列表:\n");printNode(head);printf("请输入需要插入的数据:\n");scanf("%d", &n);insert(head, n);printf("插入数据之后的链表:\n");printNode(head);return 0;
}

9.综合本章例9.9(建立链表的函数 creat)、例9.10(输出链表的函数 print)和本章习题第7题(删除链表中结点的函数dei)、第8题(插入结点的函数 insert),再编写一个主函数,先后调用这些函数。用以上5个函数组成一个程序,实现链表的建立、输出、删除和插入,在主函数中指定需要删除和插入的结点的数据。

#include <stdio.h>
#include <stdlib.h>#define CNT 3//定义节点
typedef struct node
{int num;struct node* next;
}node;//创建链表:从控制台输入数据
node* creat()
{//首先创建一个头节点,不存放有效数据node* head = (node*)malloc(sizeof(node));head->next = NULL;head->num = 0;node* p = head;printf("创建一个含有%d个数据的单链表\n", CNT);printf("请输入%d个数据:", CNT);for (int i = 0; i < CNT; i++){int n;scanf("%d", &n);node* newNode = (node*)malloc(sizeof(node));newNode->num = n;newNode->next = NULL;//链接p->next = newNode;p = p->next;}return head;
}//打印链表
void printNode(node* head)
{node* p = head->next;while (p != NULL){printf("node: %d\n", p->num);p = p->next;}
}//删除节点
void del(node* head, int val)
{//遍历链表,找到待删除的位置node* p = head->next;node* prev = head;while (p != NULL){if (p->num == val){prev->next = p->next;free(p);break;}else{prev = p;p = p->next;}}
}//插入节点
void insert(node* p, int val)
{//给p节点的后面插入新的数据node* newNode = (node*)malloc(sizeof(node));newNode->num = val;newNode->next = NULL;newNode->next = p->next;p->next = newNode;
}int main()
{printf("创建链表:\n");node* head = creat();printf("创建链表结束:\n");printf("初始链表:\n");printNode(head);printf("请输入需要插入的数据:\n");int n;scanf("%d", &n);insert(head, n);printf("插入数据: %d之后,链表的所有数据:\n",n);printNode(head);printf("请输入需要删除的数据:\n");scanf("%d", &n);del(head, n);printf("删除数据:%d之后,链表的所有数据:\n", n);printNode(head);return 0;
}

10.已有 a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。

#include <stdio.h>
#include <stdlib.h>#define NUM 5typedef struct node
{int num;float score;struct node* next;
}node;node* creat()
{printf("请输入%d个数据:学号 成绩\n", NUM);node* head = NULL;//链表的表尾node* tail = NULL;for (int i = 0; i < NUM; i++){int num;float score;scanf("%d%f", &num, &score);//创建节点node* newNode = (node*)malloc(sizeof(node));newNode->num = num;newNode->score = score;newNode->next = NULL;//插入到已有链表//判断当前链表是否为空if (head == NULL){head = tail = newNode;}else{//把新的节点插入到尾节点后面tail->next = newNode;tail = newNode;}}return head;
}//合并,排序两个链表
node* mergeList(node* a, node* b)
{//合并node* head = a;while (head->next != NULL){head = head->next;}head->next = b;head = a;//prev:未排序的第一个节点node* prev = a;//排序,选择排序while (prev->next != NULL){//每次从未排序的节点中选择一个学号最小的//放在第一个未排序节点的位置node* cur = prev->next;while (cur){if (prev->num > cur->num){//把学号最小的数据往前移动int num = prev->num;float score = prev->score;prev->num = cur->num;prev->score = cur->score;cur->num = num;cur->score = score;}cur = cur->next;}prev = prev->next;}return head;
}void printNode(node* a)
{while (a != NULL){printf("学号:%d 成绩:%f\n", a->num, a->score);a = a->next;}
}int main()
{node* a = creat();node* b = creat();printf("链表a的数据:\n");printNode(a);printf("链表b的数据:\n");printNode(b);printf("合并a和b\n");a = mergeList(a, b);printNode(a);return 0;
}

11.有两个链表 a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。

#include <stdio.h>
#include <stdlib.h>#define LEN 20typedef struct node
{int num;char name[LEN];struct node* next;
}node;//返回新链表的表头
node* del(node* a, node* b)
{node* head = a;//遍历b中的每一个节点while (b){//从a的表头开始遍历node* prev = a;node* cur = prev->next;//用头节点和b当前指向的节点进行比较if (prev->num == b->num){prev->next = NULL;//更新表头head = cur;}//用非头节点和b当前指向的节点进行比较else{while (cur){if (cur->num == b->num){//删除当前节点prev->next = cur->next;cur->next = NULL;break;}else{//继续向后遍历prev = cur;cur = cur->next;}}}//处理b的下一个节点b = b->next;}return head;
}void printNode(node* head)
{while (head){printf("%d-->%s\n", head->num, head->name);head = head->next;}
}int main()
{//建立链表node a[5] = { {3, "zhang"}, {1, "wang"},{15, "li"},{10, "zhou"},{8, "ren"} };node b[3] = { {8, "ren"}, {3, "zhang"}, {10, "zhou"}};for (int i = 0; i < 5; i++){a[i].next = &a[i + 1];}a[4].next = NULL;for (int i = 0; i < 3; i++){b[i].next = &b[i + 1];}b[2].next = NULL;printf("链表a:\n");printNode(a);printf("链表b:\n");printNode(b);node* head = del(a, b);printf("删除之后的链表:\n");printNode(head);return 0;
}

12.建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。

#include <stdio.h>
#define LEN 20typedef struct node
{int num;char name[LEN];char gender[LEN];int age;struct node* next;
}node;node* del(node* a)
{int age;printf("请输入需要删除的年龄:\n");scanf("%d", &age);//遍历删除node* prev = NULL;node* cur = a;node* head = a;while (cur){if (cur->age == age){//当前节点需要删除//头节点if (prev == NULL){//更新头节点head = cur->next;}//非头节点else{prev->next = cur->next;}//查看下一个节点cur = cur->next;}else{//当前节点不需要删除prev = cur;cur = cur->next;}}return head;
} void printNode(node* head)
{while (head){printf("%d %s %s %d\n", head->num, head->name, head->gender, head->age);head = head->next;}
}int main()
{node arr[] = { {1, "wang", "male", 20}, {2, "li", "female", 30}, {3, "zhang", "male", 20}, {4, "li", "female", 18}, {5, "cheng", "male", 20} };//建立链表for (int i = 0; i < 5; i++){arr[i].next = &arr[i + 1];}arr[4].next = NULL;printf("链表的所有数据:\n");printNode(arr);node* head = del(arr);printf("删除之后链表的剩余数据:\n");printNode(head);return 0;
}

这篇关于谭浩强【C语言程序设计】第九章习题详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/722780

相关文章

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML