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

2024-02-16 16:04

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



1.输入 3个整数,按由小到大的顺序输出。

#include <stdio.h>int main()
{int num1, num2, num3;printf("请输入3个整数:>");scanf("%d%d%d", &num1, &num2, &num3);int* pmin = &num1;int* pmid = &num2;int* pmax = &num3;if (*pmin > *pmid){int* tmp = pmin;pmin = pmid;pmid = tmp;}if (*pmin > *pmax){int* tmp = pmin;pmin = pmax;pmax = tmp;}if (*pmid > *pmax){int* tmp = pmid;pmid = pmax;pmax = tmp;}printf("由小到大为:%d %d %d\n", *pmin, *pmid, *pmax);return 0;
}

2.输入 3个字符串,按由小到大的顺序输出。

#include <stdio.h>
#include <string.h>int main()
{char str1[32], str2[32], str3[32];printf("请输入3个字符串:>\n");scanf("%s", str1);scanf("%s", str2);scanf("%s", str3);char* pmin = str1;char* pmid = str2;char* pmax = str3;if (strcmp(pmin, pmid) > 0){char* tmp = pmin;pmin = pmid;pmid = tmp;}if (strcmp(pmin, pmax) > 0){char* tmp = pmin;pmin = pmax;pmax = tmp;}if (strcmp(pmid, pmax) > 0){char* tmp = pmid;pmid = pmax;pmax = tmp;}printf("由小到大的顺序为:\n%s\n%s\n%s\n", pmin, pmid, pmax);return 0;
}

3.输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数: ①输入 10个数;②进行处理;③输出 10 个数。

#include <stdio.h>void Init(int* arr, int sz)
{printf("请输入10个整数:>\n");for (int i = 0; i < sz; i++){//arr是数组首元素地址,+i就表示数组第i个元素的地址scanf("%d", arr + i);}printf("\n");
}void Handler(int* arr, int sz)
{//将pmin和pmax都初始化为数组的首元素地址int* pmin = arr, * pmax = arr;for (int i = 0; i < sz; i++){if (*pmin > *(arr + i)){//若arr+i位置的数据比pmin位置的数据小,则把arr+i这个地址赋值给pminpmin = arr + i;}if (*pmax < *(arr + i)){//若arr+i位置的数据比pmin位置的数据大,则把arr+i这个地址赋值给pmaxpmax = arr + i;}}if (pmax == arr){pmax = pmin;}int tmp = *arr; *arr = *pmin; *pmin = tmp;tmp = *(arr + sz - 1); *(arr + sz - 1) = *pmax; *pmax = tmp;
}void Print(int* arr, int sz)
{printf("对换后的10个整数为:\n");for (int i = 0; i < sz; i++){printf("%d ", *(arr + i));}printf("\n");
}int main()
{int arr[10];Init(arr, 10);Handler(arr, 10);Print(arr, 10);return 0;
}

4. 有 n个整数,使前面各数顺序向后移 m个位置,最后 m个数变成最前面 m个数,见图 8.43。写一函数实现以上功能,在主函数中输入 n个整数和输出调整后的n个数。

#include <stdio.h>void reverse(int* arr, int n, int m)
{for (int i = 0; i < m; i++){int tmp = *(arr + n - 1);for (int j = n - 1; j > 0; j--){*(arr + j) = *(arr + j - 1);}*arr = tmp;}
}int main()
{int n = 0, m = 0;int arr[32];printf("请确定需要输入几个数字:");scanf("%d", &n);for (int i = 0; i < n; i++){scanf("%d", arr + i);}printf("请输入要向后移动的位数:");scanf("%d", &m);reverse(arr, n, m);for (int i = 0; i < n; i++){printf("%d ", *(arr + i));}return 0;
}

5.有 n个人围成一圈,顺序排号。从第1个人开始报数
(从 1到3 报数),凡报到3 的人退出圈子,问最后留下的是原来第几号的那位。

#include <stdio.h>int main()
{int total;//记录总人数int arr[128];//记录每个人所报的数int digit = 1;//记录当前要喊的数字printf("请输入总人数:");scanf("%d", &total);int remain = total;//记录剩余人数,剩余人数刚开始应等于总人数while (remain > 1)//循环至最终只剩一个人{for (int i = 1; i <= total; i++){if (*(arr + i) == 3)//第i个人是3,代表这个人已经被淘汰了continue;*(arr + i) = digit;if (digit == 3){digit = 0;//报数报道3则归0,因为下边有++操作remain--;//剩余人数-1}digit++;}}for (int i = 1; i <= total; i++){if (*(arr + i) != 3)printf("最后留下的是原来的第%d位\n", i);}return 0;
}

6.写一函数,求一个字符串的长度。在 main函数中输入字符串,并输出其长度。

#include <stdio.h>
#include <assert.h>int my_strlen(char* str)
{assert(str);char* ptr = str;while (*ptr != '\0'){ptr++;}return ptr - str;
}int main()
{char str[128] = { 0 };printf("请输入一个字符串:");gets(str);int ret = my_strlen(str);printf("长度为:%d\n", ret);return 0;
}

7.有一字符串,包含 n个字符。写一函数,将此字符串中从第 m个字符开始的全部字符复制成为另一个字符串。

#include <stdio.h>void mystrcpy(char* dst, char* src, int m)
{char* ps = src + m - 1;char* pd = dst;while (*ps != '\0'){*pd = *ps;ps++;pd++;}*pd = '\0';}int main()
{char src[32];printf("请输入一个字符串:");//从键盘获取一行数据,最大不超过30字节,放到str指向的空间中fgets(src, 30, stdin);int m = 0;printf("请输入要从第多少个字符开始拷贝:");scanf("%d", &m);char dst[32];mystrcpy(dst, src, m);printf("拷贝后的字符串为:%s\n", dst);return 0;
}

8.输入一行文字,找出其中大写字母、小写字母、空格、数字以及其他字符各有多少。

#include <stdio.h>
#include <string.h>int main()
{char str[128];printf("请输入一行文字:>");fgets(str, 125, stdin);//fgets获取一行数据的时候,末尾是有个换行字符\0的*(str + strlen(str) - 1) = '\0';char* ptr = str;int upper = 0, lower = 0, digit = 0, space = 0, other = 0;while (*ptr != '\0'){if (*ptr >= 'A' && *ptr <= 'Z'){upper++;}else if (*ptr >= 'a' && *ptr <= 'z'){lower++;}else if (*ptr >= '0' && *ptr <= '9'){digit++;}else if (*ptr == ' '){space++;}else {other++;}ptr++;}printf("大写字母:%d\n小写字母:%d\n空格:%d\n数字:%d\n其他字符:%d\n",upper, lower, space, digit, other);return 0;
}

9.写一函数,将一个3×3的整型矩阵转置。

#include <stdio.h>void reverse(int(*arr)[3])
{for (int i = 0; i < 3; i++){for (int j = i; j < 3; j++){int tmp = *(*(arr + i) + j);*(*(arr + i) + j) = *(*(arr + j) + i);*(*(arr + j) + i) = tmp;}}
}int main()
{int arr[3][3];printf("请输入一个3x3的整形矩阵:\n");for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){scanf("%d", *(arr + i) + j);}}reverse(arr);printf("将矩阵转置后为:\n");for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){printf("%d ", *(*(arr + i) + j));}printf("\n");}return 0;
}

10.将一个5×5的矩阵中最大的元素放在中心,4个角分别放4 个最小的元素(顺序为从左到右,从上到下依次从小到大存放),写一函数实现之。用 main 函数调用。

#include <stdio.h>void change(int (*arr)[5], int row, int col)
{//1.找最大的元素并放在中间int* mid = *(arr + row / 2) + (col / 2);int* max = *(arr + 0) + 0;//假设[0, 0]位置就是最大值for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){//如果第i行第j列的元素比当前位置大,则max指向新的最大值位置if (*max < *(*(arr + i) + j)){max = *(arr + i) + j;}}}int tmp = *mid; *mid = *max; *max = tmp;//2.找出4个最小的数并和4个角落进行交换//将4个角的地址保存起来int* corner[4] = { *(arr + 0) + 0, *(arr + 0) + col - 1, *(arr + row - 1) + 0, *(arr + row - 1) + col - 1 };//找最小值,需要找4次for (int i = 0; i < 4; i++){int* min = mid;//假设最小值位置为中间值的位置for (int m = 0; m < row; m++){for (int n = 0; n < col; n++){int k;for (k = 0; k < i; k++)//找第0个最小数的时候,i是0,意味着没有角落被置换{if (*(arr + m) + n == *(corner + k))break;}if (k != i)continue;if (*min > *(*(arr + m) + n))min = *(arr + m) + n;}}int tmp = *min; *min = **(corner + i); **(corner + i) = tmp;}
}int main()
{int arr[5][5];printf("请输入一个5x5的整形矩阵:\n");for (int i = 0; i < 5; i++){for (int j = 0; j < 5; j++){scanf("%d", *(arr + i) + j);}}change(arr, 5, 5);printf("--------------------------\n");for (int i = 0; i < 5; i++){for (int j = 0; j < 5; j++){printf("%2d ", *(*(arr + i) + j));}printf("\n");}return 0;
}

11.在主函数中输入10个等长的字符串。用另一函数对它们排序。然后在主函数输出这10个已排好序的字符串。

#include <stdio.h>
#include <string.h>void str_sort(char (*arr)[32], int row)
{for (int i = 0; i < 10 - 1; i++){for (int j = 0; j < 10 - 1 - i; j++){if (strcmp(*(arr + j), *(arr + j + 1)) > 0){char tmp[32];strcpy(tmp, *(arr + j));strcpy(*(arr + j), *(arr + j + 1));strcpy(*(arr + j + 1), tmp);}}}
}int main()
{char arr[10][32];printf("请输入10个字符串:\n");for (int i = 0; i < 10; i++){scanf("%s", arr + i);}str_sort(arr, 10);printf("------------------\n");for (int i = 0; i < 10; i++){printf("%s\n", *(arr + i));}return 0;
}

12.用指针数组处理上一题目,字符串不等长。

#include <stdio.h>
#include <string.h>void str_sort(char** str, int row)
{for (int i = 0; i < 10 - 1; i++){for (int j = 0; j < 10 - 1 - i; j++){if (strcmp(*(str + j), *(str + j + 1))){char* tmp = *(str + j);*(str + j) = *(str + j + 1);*(str + j + 1) = tmp;}}}
}int main()
{char arr[10][32];char* parr[10] = { 0 };printf("请输入10个字符串:\n");for (int i = 0; i < 10; i++){*(parr + i) = *(arr + i);scanf("%s", *(parr + i));}str_sort(parr, 10);printf("---------------\n");for (int i = 0; i < 10; i++){printf("%s\n", *(arr + i));}printf("---------------\n");for (int i = 0; i < 10; i++){printf("%s\n", *(parr + i));}return 0;
}

13.写一个用矩形法求定积分的通用函数,分别求
∫sinxdx, ∫cosxdx, ∫e^xdx
说明: sin, cos, exp函数已在系统的数学函数库中,程序开头要用# include<math. h>。

#include <stdio.h>
#include <math.h>double integral(double num1, double num2, int count, double (*handler)(double))
{double dx = (num2 - num1) / count;double res = 0;for (int i = 0; i < count; i++){double dh = handler(num1 + dx * i);res += dx * dh;}return res;
}int main()
{printf("请输入积分区间[num1, num2]:");double num1, num2;scanf("%lf%lf", &num1, &num2);printf("请输入分割数量:");int count;scanf("%d", &count);printf("请输入被积分函数<1-sin, 2-cos, 3-exp>:");int choice;scanf("%d", &choice);double (*var[4])(double) = { NULL, sin, cos, exp };double res = integral(num1, num2, count, var[choice]);printf("定积分结果:%lf\n", res);return 0;
}

14. 将 n个数按输入时顺序的逆序排列,用函数实现。

#include <stdio.h>void reverse(int* arr, int sz)
{int* left = arr;int* right = arr + sz - 1;while (left < right){int tmp = *left;*left = *right;*right = tmp;left++;right--;}
}int main()
{int arr[128];int n;printf("请输入数据的个数:>");scanf("%d", &n);printf("请输入数据:>");for (int i = 0; i < n; i++){scanf("%d", arr + i);}reverse(arr, n);printf("逆序排列后为:");for (int i = 0; i < n; i++){printf("%d ", *(arr + i));}return 0;
}

15.有一个班4 个学生,5门课程。①求第1门课程的平均分;②找出有两门以上课程不及格的学生,输出他们的学号和全部课程成绩及平均成绩;③找出平均成绩在 90分以上或全部课程成绩在85分以上的学生。分别编3个函数实现以上3个要求。

#include <stdio.h>float course_avg(float(*arr)[5], int row, int col)
{float sum = 0;for (int i = 0; i < row; i++){sum += *(*(arr + i) + 0);}return (sum / row);
}float stu_avg(float* score, int sz)
{float sum = 0;for (int i = 0; i < sz; i++){sum += *(score + i);}return (sum / sz);
}void fail(float(*arr)[5], int row, int col)
{for (int i = 0; i < row; i++){int fail_count = 0;for (int j = 0; j < col; j++){if (*(*(arr +i) + j) < 60){fail_count++;}}if (fail_count > 2){printf("%d号学生有两门课以上成绩不及格。\n", i);printf("这个学生的平均成绩是:%.2f\n", stu_avg(*(arr + i), col));}}
}void print_stu_score(float* score, int sz)
{printf("此学生的所有成绩如下:");for (int i = 0; i < sz; i++){printf("%.2f ", *(score + i));}printf("\n");
}void excellent(float(*arr)[5], int row, int col)
{for (int i = 0; i < row; i++){int course_count = 0;float sum = 0; for (int j = 0; j < col; j++){if (*(*(arr + i) + j) > 85){course_count++;}sum += *(*(arr + i) + j);}if ((sum / col) > 90 || course_count == col){printf("%d号学生是好学生!\n", i);print_stu_score(*(arr + i), col);}}
}int main()
{float score[4][5] = {{32, 48, 56, 36, 75},{98, 70, 99, 100, 97},{87, 88, 89, 86, 87},{68, 69, 75, 78, 80}};float cour_avg_score = course_avg(score, 4, 5);printf("第1门课的平均分:%.2f\n", cour_avg_score);fail(score, 4, 5);excellent(score, 4, 5);return 0;
}

16.输入一个字符串,内有数字和非数字字符,例如:
A123×456 17960?302tab5876
将其中连续的数字作为一个整数,依次存放到一数组 a中。例如,123 放在 a[0],456 放在a[1]⋯⋯统计共有多少个整数,并输出这些数。

#include <stdio.h>int main()
{char str[1024] = { 0 };fgets(str, 1023, stdin);char res[128][32];int row = 0, col = 0;char* ptr = str;while (*ptr != '\0'){if (*ptr >= '0' && *ptr <= '9'){while (*ptr >= '0' && *ptr != '\0' && *ptr <= '9'){*(*(res + row) + col) = *ptr;col++;ptr++;}*(*(res + row) + col) = '\0';row++;col = 0;if (*ptr == '\0')break;}ptr++;}printf("共找到%d个数字\n", row);for (int i = 0; i < row; i++){printf("%s\n", *(res + i));}return 0;
}

17.写一函数,实现两个字符串的比较。即自己写一个 strcmp函数,函数原型为
int strcmp(char *p1, char *p2);
设 p1指向字符串 s1, p2指向字符串 s2。要求当s1=s2 时,返回值为0;若sl≠s2,返回它们二者第1个不同字符的 ASCII码差值(如"BOY"与"BAD",第2个字母不同,O 与 A 之差为79-65=14)。如果s1>s2,则输出正值;如果s1<s2,则输出负值。

#include <stdio.h>
int my_strcmp(char* p1, char* p2)
{while (*p1 != '\0' && *p2 != '\0' && *p1 == *p2){p1++;p2++;}return *p1 - *p2;
}int main()
{char str1[128];char str2[128];printf("请输入要比较的两个字符串:>\n");scanf("%s%s", str1, str2);int ret = my_strcmp(str1, str2);printf("%d\n", ret);return 0;
}

18.编一程序,输入月份号,输出该月的英文月名。例如,输入 3,则输出"March", 要求用指针数组处理。

#include <stdio.h>int main()
{char* month[13] = {NULL,"January","February","March","April","May","June","July","August","September","October","November","December"};int input;printf("请输入月份:>");scanf("%d", &input);if (input < 1 || input > 12){printf("输入有误!\n");return -1;}printf("%s\n", *(month + input));return 0;
}

19.(1) 编写一个函数 new,对 n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配 n个字节的内存空间。

(2)写一函数free,将前面用 new 函数占用的空间释放。free(p)表示将 p(地址)指向的单元以后的内存段释放。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>char* my_news(int n)
{char* p = (char*)malloc(n);return p;
}void my_free(char* p)
{free(p);p = NULL;
}int main()
{char* data = my_news(32);strcpy(data, "hello world!");printf("%s\n", data);my_free(data);printf("%s\n", data);return 0;
}

20.用指向指针的指针的方法对5个字符串排序并输出。

#include <stdio.h>
#include <string.h>void str_sort(char** ppstr, int sz)
{for (int i = 0; i < sz - 1; i++){for (int j = 0; j < sz - 1 - i; j++){if (strcmp(*(ppstr + j), *(ppstr + j + 1)) > 0){char tmp[32];strcpy(tmp, *(ppstr + j));strcpy(*(ppstr + j), *(ppstr + j + 1));strcpy(*(ppstr + j + 1),tmp);}}}
}int main()
{char str[5][32];printf("请输入5个字符串:>\n");for (int i = 0; i < 5; i++){scanf("%s", str + i);}char* pstr[5];for (int i = 0; i < 5; i++){pstr[i] = *(str + i) + 0;}str_sort(pstr, 5);printf("排序后为:\n");for (int i = 0; i < 5; i++){printf("%s ", *(str + i));}return 0;
}

21.用指向指针的指针的方法对n个整数排序并输出。要求将排序单独写成一个函数。n个整数在主函数中输入,最后在主函数中输出。

#include <stdio.h>void int_sort(int** pparr, int sz)
{for (int i = 0; i < sz - 1; i++){for (int j = 0; j < sz - 1 - i; j++){if (**(pparr + j) > **(pparr + j + 1)){int tmp = **(pparr + j);**(pparr + j) = **(pparr + j + 1);**(pparr + j + 1) = tmp;}}}
}int main()
{int arr[128] = { 0 };int n;printf("请确定需要输入的数字个数:>");scanf("%d", &n);printf("请输入数字:>");for (int i = 0; i < n; i++){scanf("%d", arr + i);}int* parr[128];for (int i = 0; i < n; i++){parr[i] = arr + i;}int_sort(parr, n);printf("排序后为:");for (int i = 0; i < n; i++){printf("%d ", *(arr + i));}return 0;
}

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



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

相关文章

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、装