谭浩强【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

相关文章

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

Go路由注册方法详解

《Go路由注册方法详解》Go语言中,http.NewServeMux()和http.HandleFunc()是两种不同的路由注册方式,前者创建独立的ServeMux实例,适合模块化和分层路由,灵活性高... 目录Go路由注册方法1. 路由注册的方式2. 路由器的独立性3. 灵活性4. 启动服务器的方式5.

Java中八大包装类举例详解(通俗易懂)

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,... 目录一、包装类(Wrapper Class)1、简要介绍2、包装类特点3、包装类用途二、装箱和拆箱1、装