C语言程序设计第五版谭浩强课后答案

C语言程序设计第五版第八章答案

  • C语言程序设计第五版谭浩强课后答案
    • 第八章 善于利用指针
      • 1. 输入3个整数,要求按由小到大的顺序输出。
      • 2. 输入3个字符串,要求按由小到大的顺序输出。
      • 3. 输入10个整数,将其中最小的数与第一个数对换, 把最大的数与最后一个数对换。
      • ①输人10个数;
      • ②进行处理;
      • ③输出10个数。
      • 4. 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面m个数,见图8.43。 写一函数实现以上功能,在主函数中输人n个整数和输出调整后的n个数。
      • 5. 有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
      • 6. 写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
      • 7. 有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。
      • 8. 输入一行文字,找出其中大写字母、小写字母、空格、数字以及其他字符各有多少。
      • 9. 写一函数,将一个3x3的整型矩阵转置。
      • 10. 将一个5x5的矩阵中最大的元素放在中心,4个角分别放4个最小的元素(顺序为从左到右,从上到下依次从小到大存放),写一函数实现之。用main函数调用。
      • 11. 在主函数中输入10个等长的字符串。用另一函数对它们排序。然后在主函数输出这10个已排好序的字符串。
      • 12. 用指针数组处理上一题目,字符串不等长。
      • 13. 写一个用矩形法求定积分的通用函数,分别求∫01sinxdx,∫01cosxdx,∫01exdx,\int_0^1 sinxdx, \quad \int_0^1 cosxdx, \quad \int_0^1 e^xdx,01sinxdx,01cosxdx,01exdx, ,说明: sin,cos,exp 函数已在系统的数学函数库中,程序开头要用#include

第八章 善于利用指针

本章习题均要求使用指针方法处理。

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

解题思路: 先获取到三个变量的地址,然后获取三个数据,通过指针进行比较转换即可

答案:

#include <stdio.h>void swap(int *p_a, int *p_b)
{int temp = *p_a;*p_a = *p_b;*p_b = temp;
}
int main()
{int a, b, c, *p_a = &a, *p_b = &b, *p_c = &c;   // 获取每个变量空间的地址printf("Please enter three numbers:");scanf_s("%d%d%d", p_a, p_b, p_c);if (*p_a > *p_b) {swap(p_a, p_b);//通过指针进行指向空间内的数据交换}if (*p_a > *p_c) {swap(p_a, p_c);}if (*p_b > *p_c) {swap(p_b, p_c);}printf("%d %d %d\n", *p_a, *p_b, *p_c);system("pause");return 0;
}

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

解题思路: 字符串的比较可以使用strcmp函数,返回值>0表示大于,返回值小于0表示小于,返回追等于0表示相同。其他的比较排序思路与数字的排序交换没有区别,逐个进行比较先找出最大的,然后找出第二大的。

答案:

#include <stdio.h>
int main()
{char str[3][32]; char *p[3];printf("Please enter three strings:");for (int i = 0; i < 3; i++) {p[i] = str[i];scanf_s("%s", p[i], 32);//后边的数字限制缓冲区边界,防止缓冲区溢出访问越界}//让p[0]和p[1]/p[2]分别进行比较,找出最大的字符串,i+1之后,则让p[1]和p[2]进行比较,找出第二大//i循环总个数-1次,最后一个是不需要比较的for (int i = 0; i < 2; i++) {for (int j = i + 1; j < 3; j++) { if (strcmp(p[i], p[j]) > 0) {char *tmp = p[i]; p[i] = p[j]; p[j] = tmp;}}}printf("%s %s %s\n", p[0], p[1], p[2]);system("pause");return 0;
}

3. 输入10个整数,将其中最小的数与第一个数对换, 把最大的数与最后一个数对换。

写3个函数:

①输人10个数;

②进行处理;

③输出10个数。

解题思路: 在进行数值逐个比较的同时找到最小值的空间地址以及最大值的空间地址,使用这两个空间中的数据最终与第一和最后数据进行对换即可。

答案:

#include <stdio.h>void input(int *arry, int len)
{for (int i = 0; i < len; i++) {scanf_s("%d", &arry[i]);}
}
void print(int *arry, int len)
{for (int i = 0; i < len; i++) {printf("%d ", arry[i]);}printf("\n");
}
void handle(int *arry, int len)
{int max_num = arry[0], min_num = arry[0];int *p_max = NULL, *p_min = NULL;for (int i = 1; i < len; i++) {if (min_num > arry[i]) {//逐个比对后找出最小值min_num = arry[i];p_min = &arry[i];  //逐个比对后找到最小值的空间地址}if (max_num < arry[i]) {//逐个比对后找出最大值max_num = arry[i];p_max = &arry[i];   //逐个比对后找到最大值的空间地址}}int tmp;tmp = *p_min; *p_min = arry[0]; arry[0] = tmp;  //最小值与第一个数据交换tmp = *p_max; *p_max = arry[len - 1]; arry[len - 1] = tmp;//最大值与最后一个数据交换
}
int main()
{int arry[10];printf("Please enter ten nums:");input(arry, 10);handle(arry, 10);print(arry, 10);system("pause");return 0;
}

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

解题思路: 找出倒数第m个数据,从这里开始保存倒数第m位置的数据,因为倒数第m位置的数据要放到数组最前方,将m之前的数据向后偏移一位,然后将数组第一个位置的数据替换为保存的m位的数据,逐个往后递增即可。

答案:

#include <stdio.h>
void move(int *arry, int n, int m)
{int end_idx = n - m;//找到倒数第m个数据的位置,也就是要移动到数组首部的数据的起始位置for (int i = 0; i < m; i++) {int *p = arry + end_idx + i;//从倒数第m个数据的位置开始逐渐向后偏移直到数组尾部int tmp = *p;//获取到这个位置的值,用于数组前边数据向后偏移1位之后,向数组第i位赋值for (int j = end_idx + i; j > i; j--) {//从第i位开始逐个向后偏移一位*p = *(p - 1);p--;}*(arry + i) = tmp;//数组的前第i个数字逐个替换为后边被覆盖的值}
}
int main()
{int number[32], n, m, i;printf("Please enter the number of numbers: ");scanf_s("%d", &n);//先确定要输入多少个数字printf("Please enter %d numbers: ", n);for (i = 0; i < n; i++) {scanf_s("%d", &number[i]);//输入指定个数的数字}printf("Number of positions to move: ");scanf_s("%d", &m);//确定要向后移动多少个位置move(number, n, m);for (i = 0; i < n; i++) {printf("%d ", number[i]);}printf("\n");system("pause");return 0;
}

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

解题思路: 从第一个人开始,逐个报数,谁报3就退出,并且重置报数,直到最后一个人后,又重新从第一个人继续报数,直到最终只剩一个人的时候退出即可。

答案:

#include <stdio.h>
int main()
{int people[128], n;printf("Please input how many people: ");scanf_s("%d", &n);for (int i = 0; i < n; i++) {people[i] = i + 1; //对每个人顺序排号}int remain = n;int num_off = 0;int *p = NULL;while (remain > 1) {p = people;while (p != people + n) { // 每次从第一个位置开始,直到最后一个位置,报数是一直递增的if ((*p) != 0) {//若这个位置人还在num_off++; //则报数if (num_off == 3) {//否则当前的人即将要报的数字是3*p = 0;  //则剔除这个人num_off = 0; //并且重新开始计数,下边会++,所以是从1开始报数remain--;//剩余人数-1}}p++;}}for (int i = 0; i < n; i++) {if (people[i] != 0) {printf("Serial number of the remaining person:%d\n", people[i]);}}printf("\n");system("pause");return 0;
}

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

解题思路: 字符串以\0作为结尾,则从第一个字符开始向后移动遇到\0认为字符串结束。

答案:

#include <stdio.h>
int mystrlen(char *str)
{int len = 0;char *ptr = str;while (*ptr != '\0') {ptr++;len++;}return len;
}
int main()
{char buf[1024];printf("Please enter a string: ");scanf_s("%s", buf, 1024);printf("string len:%d\n", mystrlen(buf));system("pause");return 0;
}

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

解题思路: 当字符串指针移动到源字符串的第m位时,则开始向另一个缓冲区中写入剩下的数据

答案:

#include <stdio.h>
#include <string.h>int main()
{char buf1[1024], buf2[1024];printf("Please enter a string: ");scanf_s("%s", buf1, 1024);int m;printf("Please enter a location to start copying: ");scanf_s("%d", &m);if (m < 0 || m > strlen(buf1)) {//检测输入的位置是否合法printf("Illegal location entered\n");return -1;}char *ptr1 = buf1 + m; // 从第m个位置开始复制新数据char *ptr2 = buf2;while (*ptr1 != '\0') {*ptr2++ = *ptr1++;}*ptr2 = '\0';//不要忘了字符串结尾标志printf("%s\n", buf2);system("pause");return 0;
}

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

解题思路: 字符可以直接进行比较,但是要注意字符串中的数字是字符数字,必须以字符的形式比较,也就是加上单引号

答案:

#include <stdio.h>
#include <string.h>int main()
{char buf[1024];printf("Please enter a string: ");gets_s(buf, 1024);int upper_count = 0, lower_count = 0, digit_count = 0, space_count = 0, other_count = 0;char *ptr = buf;while (*ptr != '\0') {if (*ptr >= 'A' && *ptr <= 'Z') { //大写字母upper_count++;}else if (*ptr >= 'a' && *ptr <= 'z'){//小写字母lower_count++;}else if (*ptr >= '0' && *ptr <= '9') {//数字字符digit_count++;}else if (*ptr== ' ') {//空格字符space_count++;}else { //其他字符other_count++;}ptr++;}printf("upper:%d; lower:%d; digit:%d; space:%d; other:%d\n", \upper_count, lower_count, digit_count, space_count, other_count);system("pause");return 0;
}

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

解题思路: 矩阵转置就是行变列,列变行,说白了就是 arry[i][j] 转换为 arry[j][i] ; 但是需要注意的是,

一. 因为行列个数可能并非相同,转换后行数或者列数变多了或者变少,因此不能直接转换。需要重新申请空间存储转换后的数据。

二. 二维数组是线性扁平化存储的,无法确定列数的情况下传参后,在函数中使用时需要头指针向后偏移 列数*第n行 才能访问到第n行的数据。例如在函数中访问 arry[i][j] ,需要通过arry + col_num*i + j 方式进行访问。

答案:

#include <stdio.h>
int **transform(int **arry, int row_count, int col_count)
{//列变行,行变列,则行的个数是以前列的个数,列的个数是以前行的个数int **p = NULL;//矩阵中有多少行,取决于以前有多少列,然后申请地址空间p = (int **)malloc(sizeof(int *) * col_count);for (int i = 0; i < col_count; i++) {//一行中有多少列,取决于以前有多少行,然后申请空间p[i] = (int *)malloc(sizeof(int) * row_count); }for (int i = 0; i < col_count; i++) {for (int j = 0; j < row_count; j++) {//二维数组的存储是扁平化的, 访问第j行第i列的数据,应该是 arry + j*列数 + i//j是新数组的列,但是是源数组的行p[i][j] = (arry + col_count * j)[i]; }}return p;
}
int main()
{int arry[3][4];printf("Please enter a 3 x 4 matrix: \n");for (int i = 0; i < 3; i++) {for (int j = 0; j < 4; j++) {scanf_s("%d", &arry[i][j]);} }int **p = transform(arry, 3, 4);printf("\n");for (int i = 0; i < 4; i++) {for (int j = 0; j < 3; j++) {printf("%d ", p[i][j]);}free(p[i]); // 释放二级指针中每个一级指针申请的空间printf("\n");}free(p);//释放总体二级指针的空间system("pause");return 0;
}

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

解题思路: 将二维数组当做一维数组进行处理比较方便,而二维数组本身就是扁平化存储,所以直接使用首地址即可。

先遍历找到最大值,将其与中间数字交换,而中间数字的下标就是数字总数除以2;

其次寻找四次最小值,每次寻找的时候将最小值的下标记录起来,前提是这个数字如果已经是选中的最小数字之一,则需要跳过,也就是只跟剩余的数字作比较。(第二次开始遍历找最小数字的时候,千万不能与第一个最小数进行比较,否则永远都只有一个最小数)。

答案:

#include <stdio.h>
#include <string.h>
void transform(int *arry, int col_row)
{//找到最大值int max = arry[0], max_idx;for (int i = 0; i < col_row * col_row; i++) {if (max < arry[i]) max = arry[i];//找出最大数max_idx = i;}//行列相乘得到总数量,除以2后加1则为中心点(暂时不考虑偶数的情况)int center_idx = (col_row * col_row) / 2;int tmp = arry[cen ter_idx]; arry[center_idx] = arry[max_idx]; arry[max_idx] = tmp;//找到四个最小值int min_idx[4];for (int i = 0; i < 4; i++) {//循环4次获取到最小值int min_tmp = arry[col_row * col_row - 1];for (int j = 0; j < col_row * col_row; j++) {//遍历所有数据,逐个比较获取最小值int k = 0;for (; k < i; k++) {//但是要注意如果某个下标的数据已经是获取过的最小值,则不能进行判断(因为这个肯定是最小的)if (j == min_idx[k]) break;}if (k != i) { continue; }//k和i不同表示j这个坐标已经是找到的最小的几个数字之一,则找下一个判断if (min_tmp > arry[j]) { // 相当于在剩下的数中找到最小的那个数字min_tmp = arry[j];min_idx[i] = j; //并且记录这个数字的位置}}}int change_idx[4];//先计算四个角的下标,便于后边进行交换change_idx[0] = 0;//第一个要置换的数据的下标,也就是左上角change_idx[1] = col_row - 1;//第二个要置换的数据的下标,也就是右上角change_idx[2] = col_row * (col_row - 1);//第一个要置换的数据的下标,也就是左下角change_idx[3] = (col_row * col_row) - 1;//第一个要置换的数据的下标,也就是右下角for (int i = 0; i < 4; i++) {int tmp = arry[change_idx[i]]; arry[change_idx[i]] = arry[min_idx[i]]; arry[min_idx[i]] = tmp;}return ;
}
int main()
{int arry[5][5];printf("Please enter a 5x5 matrix: \n");for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {scanf_s("%d", &arry[i][j]);} }transform(*arry, 5);//将二维数组当做一维数组传入处理,并且传入行列数printf("\n");for (int i = 0; i < 5; i++) {for (int j = 0; j < 5; j++) {printf("%d ", arry[i][j]);}printf("\n");}system("pause");return 0;
}

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

解题思路: 排序方式与数字比较没什么不同,先遍历比较找出最大的字符串,与第一个字符串进行交换,然后剩下的进行比较找出最大的字符串与第二个交换…

需要主机的就是字符串的比较采用strcmp接口,返回值大于0表示第一个字符串大于第二个字符串

答案:

#include<stdio.h>
#include<string.h>
void sort(char s[10][32])
{int i, j;for (i = 0; i < 10; i++){for (j = i; j < 10; j++){if (strcmp(s[i], s[j])> 0){char tmp[32];strcpy_s(tmp, 32, s[i]);strcpy_s(s[i], 32, s[j]);strcpy_s(s[j], 32, tmp);}}}
}
int main()
{char str[10][32];printf("Please enter ten strings:\n");for (int i = 0; i < 10; i++){scanf_s("%s", str[i], 32);}sort(str);printf("\n");for (int i = 0; i < 10; i++){printf("%s\n", str[i]);}system("pause");return 0;
}

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

解题思路: 与数字的比较没什么区别,只不过需要采用strcmp进行字符串的大小比较,使用指针实现需要在最早接收数据的时候就采用字符串指针数组,这样的好处在于指针的指向可以直接通过赋值进行改变,而指针数组中的字符串的顺序只需要交换不同字符串的地址就可以实现

答案:

#include<stdio.h>
#include<string.h>
void sort(char *s[10])
{int i, j;for (i = 0; i < 10; i++){for (j = i; j < 10; j++){if (strcmp(s[i], s[j])> 0){char *tmp = s[i]; //指针的好处在于直接通过赋值可以改变指向s[i] = s[j];  //只要交换了字符串的地址就实现了字符串的交换s[j] = tmp;//因此通过指针指向的交换就能够实现数组中字符串的排序}}}
}
int main()
{char *str[10];printf("Please enter ten strings:\n");for (int i = 0; i < 10; i++) {str[i] = malloc(32);//为每一个指针分配空间scanf_s("%s", str[i], 32);}sort(str);printf("\n");for (int i = 0; i < 10; i++){printf("%s\n", str[i]);free(str[i]);}system("pause");return 0;
}

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

解题思路:

矩形法,学过高等数学就知道化曲为直的思想。将定积分化为多个函数连续的和。基本思想是将区间[a,b]化成n等分,当n越大的时候结果越准确。图形化成一小块一小块的矩形。底边长都为(b-a)/n.高为每个等分点的函数值。然后将每个矩形的面积相加即为所求。

因为被分成n等分,就可以认为每一等分是一个矩形,那么每一矩形的面积为: 每一个矩形面积为:

Sn=f(x)(b-a)/n ;总面积为:S=S1+S2+…+Sn;具体计算过程根据公式套即可

这里主要在于函数指针的应用,将函数作为参数传递给另一个函数,在另一个函数中进行调用的方式向外提供统一接口,而接口内的处理方式随着传入的函数而不同。

答案:

#include<stdio.h>
#include<math.h>double integral(double(*handler)(double), double a, double b, int n)
{double i,s = 0;double h = (b - a) / n;for (i = a; i <= b; i += h){s += handler(i) * h;}return s;
}
int main()
{double a, b;int n = 200000; // 区间划分个数int func_idx; // 计算函数选择idprintf("Please enter the lower and upper limit of integration:");scanf_s("%lf %lf", &a, &b);printf("Please enter specific calculation function(1-sin/2-cos/3-exp): ");scanf_s("%d", &func_idx);switch (func_idx) {case 1:printf("The integral of sin(x) is:%lf\n", integral(sin, a, b, n)); break;case 2:printf("The integral of cos(x) is:%lf\n", integral(cos, a, b, n)); break;case 3:printf("The integral of exp(x) is:%lf\n", integral(exp, a, b, n)); break;default:printf("function id error\n");return -1;}system("pause");return 0;
}

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

解题思路: 定义两个指针,一个指向数组头部,一个指向数组尾部,头部每次+1,尾部每次-1;则在头部小于尾部的情况下进行数据交换即可。

答案:

#include<stdio.h>
#include<math.h>void reorder(int *arry, int n)
{int *start = arry;int *end = arry + n - 1;for (; start < end; start++, end--) {int tmp = *start;*start = *end;*end = tmp;}return;
}int main()
{int arry[10];printf("Please enter ten numbers:");for (int i = 0; i < 10; i++) {scanf_s("%d", &arry[i]);}reorder(arry, 10);printf("\n");for (int i = 0; i < 10; i++) {printf("%d ", arry[i]);}printf("\n");system("pause");return 0;
}

15. 有一个班4个学生,5门课程。

①求第1门课程的平均分;

②找出有两门以上课程不及格的学生,输出他们的学号和全部课程成绩及平均成绩;

③找出平均成绩在90分以上或全部课程成绩在85分以上的学生。

分别编3个函数实现以上3个要求。

解题思路: 4个学生,5门课程就是一个4x5的二维数组,

  1. 求第一门课的平均分,就是将第0列数据相加除以学生人数
  2. 遍历每个学生的成绩,判断不及格次数,若大于2则输出信息即可
  3. 统计每个学生总成绩,以及对每门课程成绩进行判断即可

答案:

#include<stdio.h>
#include<math.h>float avg(int arry[][5], int n)
{float sum = 0;for (int i = 0; i < n; i++) {sum += arry[i][0];}printf("Average of course 1:%f\n", (sum / n));return (sum / n);
}
void fail(int arry[][5], int n)
{printf("Information on students who fail in more than two courses: ");for (int i = 0; i < n; i++) {int sum = 0, fail_count = 0;for (int j = 0; j < 5; j++) {if (arry[i][j] < 60) {fail_count++;}}if (fail_count <= 2) {continue;}printf("seq:%d ", i + 1);printf("score: ");for (int j = 0; j < 5; j++) {sum += arry[i][j];printf("%d ", arry[i][j]);}printf("avg:%d ", sum / 5);printf("\n");}return;
}
void excellent(int arry[][5], int n)
{int i, j;for (i = 0; i < n; i++) {int sum = 0, count = 0;for (j = 0; j < 5; j++) {sum += arry[i][j]; //计算总分用于计算平均分if (arry[i][j] > 85) {count++; //若每门课都大于85则count总会与j同步++}}if ((sum / 5) > 90 || count == j) {printf("Excellent students: %d\n", i + 1);}}return;
}int main()
{int arry[4][5];printf("Please enter a 4x5 matrix:\n");for (int i = 0; i < 4; i++) {for (int j = 0; j < 5; j++) {scanf_s("%d", &arry[i][j]);}}avg(arry, 4);fail(arry, 4);excellent(arry, 4);printf("\n");system("pause");return 0;
}

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

解题思路: 遇到数字字符,则开始统计连续数字字符的个数,统计完毕后,则从右往左每次乘以10(除了个位数)作为数字的单位,最终相加得到数字;然后越过这个数字,从后边继续查找。

答案:

#include<stdio.h>
#include<string.h>void count_digit(char *str)
{int digit[32], count = 0;char *ptr = str;int i = 0, str_len = strlen(str);while (i < str_len) {if (*(ptr+i) >= '0' && *(ptr+i) <= '9') {int len = 1;//用于统计连续数字的个数while (*(ptr + i + len) >= '0' && *(ptr + i+ len) <= '9' && (i+len) < str_len) {//找出从当前位置连续数字的个数len++;}int sum = *(ptr + i + len - 1) - '0';//先获取个位数的数据int unit = 1;//每一位的单位,从十位开始每次乘以10作为单位for (int j = len - 2; j >= 0; j--) {//从右往左逐个处理unit *= 10;sum += (*(ptr + i + j) - '0') * unit;}digit[count++] = sum;i += len; // i需要加上len的长度,越过这个数字,防止一个连续数字中的字符重复处理continue;}i++;}for (int i = 0; i < count; i++) {printf("%d ", digit[i]);}return;
}
int main()
{char buf[1024] = { 0 };printf("Please enter a string with numbers:\n");gets_s(buf, 1024);count_digit(buf);printf("\n");system("pause");return 0;
}

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

解题思路: 使用两个指针指向两个字符串首部,逐个往后进行比较,不相等的时候则将数据进行相减,作为返回值。

答案:

#include<stdio.h>
#include<string.h>int mystrcmp(char *str1, char *str2)
{char *ptr1 = str1;char *ptr2 = str2;int res;while (*ptr1 != '\0' && *ptr2 != '\0') {if (*ptr1 != *ptr2) {res = *ptr1 - *ptr2;break;}ptr1++;ptr2++;}if (*ptr1 == '\0' || *ptr2 == '\0') {//注意一个字符串到达结尾或者两个都到达结尾的情况res = *ptr1 - *ptr2;}return res;
}
int main()
{char buf1[1024] = { 0 };char buf2[1024] = { 0 };while (1) {printf("Please enter two strings:\n");gets_s(buf1, 1024);gets_s(buf2, 1024);printf("mystrcmp:%d", mystrcmp(buf1, buf2));printf("\n");}system("pause");return 0;
}

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

解题思路: 首先定义字符串指针数字,数组中每一个元素都存放一个字符串指针,每个指针指向不同字符串的位置。则输入月份数字后,根据下标获取对应月份字符串的地址即可

答案:

#include<stdio.h>
int main()
{int month;char* Month[12] = { "January","February","March","April","May","June","July","August","September","October","November","December" };while (1) {printf("Please enter the month: ");scanf_s("%d", &month);if (month < 1 && month>12) {printf("Input error, Month should be greater than 0 and less than 12\n");}printf("%s\n", Month[month - 1]);}return 0;
}

19.(1) 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。(2)写一函数free,将前面用new函数占用的空间释放。free§表示将p(地址)指向的单元以后的内存段释放。

解题思路: 封装malloc函数申请空间,封装free函数释放空间;

答案:

#include <stdio.h>
#include <stdlib.h>void *mynew(int n)
{return malloc(n);
}
void myfree(char *p)
{return free(p);
}
int main()
{int num;char *str = NULL;printf("Please enter number: ");scanf_s("%d", &num);printf("before new p--%p:%s\n", str, str);//申请空间之前,查看指针的地址和指向空间数据str = (char*)mynew(num);printf("after new p--%p:%s\n", str, str);//申请空间之后,查看指针的地址和指向空间数据printf("Please enter a string:");scanf_s("%s", str, num);printf("before free p--%p:%s\n", str, str);//释放空间之前,查看指针的地址和指向空间数据myfree(str);printf("after free p--%p:%s\n", str, str);//释放空间之后,查看指针的地址和指向空间数据system("pause");return 0;
}

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

**解题思路:**指向指针的指针其实就是二级指针,使用二级指针的保存一级指针的地址,让这个一级指针指向具体的数据空间; 定义一个字符串指针数组包含5个元素,每个元素可以保存一个字符串的首地址,而这个地址指向的是具体的字符串数据空间,通过指针访问实现对指向空间内的字符串进行比较排序交换即可。

答案:

#include<stdio.h>
#include<string.h>
void sort(char *s[10])
{int i, j;for (i = 0; i < 10; i++){for (j = i; j < 10; j++){if (strcmp(s[i], s[j])> 0){//s[i]保存的就是一个字符串的首地址char *tmp = s[i]; //指针的好处在于直接通过赋值可以改变指向s[i] = s[j];  //只要交换了字符串的地址就实现了字符串的交换s[j] = tmp;//因此通过指针指向的交换就能够实现数组中字符串的排序}}}
}
int main()
{char *str[5];//定义字符串指针数组,可以分别保存指向5个字符串所在空间首地址printf("Please enter five strings:\n");for (int i = 0; i < 5; i++) {str[i] = malloc(32);//为每一个指针分配空间scanf_s("%s", str[i], 32);}sort(str);printf("\n");for (int i = 0; i < 5; i++){printf("%s\n", str[i]);free(str[i]);}system("pause");return 0;
}

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

解题思路: 指向指针的指针其实就是二级指针,使用二级指针的保存一级指针的地址,让这个一级指针指向具体的数据空间。排序就是按照每个元素指针指向空间中的数据进行比对排序即可。

答案:

#include<stdio.h>
#include<string.h>
void sort(int *s[], int len)
{int i, j;for (i = 0; i < len; i++) {for (j = i; j < len; j++) {//s[i]就是s指针数组中第i个元素保存的一级指针,再次解引用就是最终的数据空间if (*(s[i]) > *(s[j])) {int tmp = *(s[i]); //指针的好处在于直接通过赋值可以改变指向*(s[i]) = *(s[j]);  //只要交换了字符串的地址就实现了字符串的交换*(s[j]) = tmp;//因此通过指针指向的交换就能够实现数组中字符串的排序}}}
}
int main()
{int *integers;int count = 0;printf("Please enter the number of count: ");scanf_s("%d", &count);integers = (int*)malloc(count * sizeof(int));//为指针申请count个int空间用于存放输入的数据int **p = (int **)malloc(count * sizeof(int*));//为指针申请count个int*空间用于存放int空间的首地址printf("Please enter %d integers: \n", count);for (int i = 0; i < count; i++) {p[i] = integers + i; //将数组中每个int元素空间的首地址赋值给指针数组中的各个元素scanf_s("%d", p[i]);//p[i]就保存时第i个数据的地址,因此这里不用取地址}sort(p, count);for (int i = 0; i < count; i++) {printf("%d ", integers[i]);}printf("\n");free(integers);free(p);system("pause");return 0;
}

这个B站上的视频c语言从入门到进阶,老师讲的相当好

C语言程序设计第五版谭浩强更多习题答案

C语言程序设计第五版谭浩强 第七章答案
C语言程序设计第五版谭浩强 第九章答案

C程序设计第五版谭浩强课后答案 第八章习题答案相关推荐

  1. C语言程序设计第五版谭浩强课后答案 第九章习题答案

    C语言程序设计第五版谭浩强第九章答案 1.定义一个结构体变量(包括年.月.日).计算该日在本年中是第几天,注意闰年问题. 2.写一个函数days,实现第1 题的计算.由主函数将年.月.日传递给days ...

  2. C语言程序设计第五版谭浩强课后答案 第六章《利用数组处理批量数据》习题答案 (大一大二、考研、计算机二级必看)

    第六章<利用数组处理批量数据>习题答案 1. 用筛选法求100之内的素数 2. 用选择法对10个整数排序 3. 求一个3 X 3的整形矩阵对角线元素之和 4. 有一个已经排好序的数组,要求 ...

  3. C语言程序设计第五版谭浩强著 第7章习题以及答案 函数系列

    1.写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果.两个整数由键盘输入. #include<stdio.h> void main(void) {in ...

  4. C语言程序设计第五版谭浩强 第七章答案

    C语言程序设计第五版谭浩强著 第七章答案 第七章 用函数实现模块化程序设计 1.写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果.两个整数由键盘输人. 题目解析: ...

  5. C语言程序设计第五版 谭浩强 第四章 课后习题 答案

    谭浩强C语言程序设计第五版 第4章 课后习题 答案 点我看视频讲解+可运行源码 记得一键三连哦 第四章 选择结构程序设计 1. 什么是算术运算?什么是关系运算?什么是逻辑运算? [答案解析] 算熟运算 ...

  6. 《C语言程序设计》第五版谭浩强课后答案 第九章《用户自己建立数据类型​》习题答案 (大一大二、考研、计算机二级必看)

    第九章<用户自己建立数据类型​>习题答案 1.定义一个结构体变量(包括年.月.日).计算该日在本年中是第几天,注意闰年问题. 2.写一个函数days,实现第1 题的计算.由主函数将年.月. ...

  7. C语言程序设计第五版 谭浩强目录大纲

    第1章程序设计和C语言1 1.1什么是计算机程序1 1.2什么是计算机语言1 1.3C语言的发展及其特点3 1.4最简单的C语言程序5 1.4.1最简单的C语言程序举例5 1.4.2C语言程序的结构9 ...

  8. C语言程序设计第五版谭浩强著 第五章部分课后习题答案

    #include<stdio.h> main() {int x,y,m,n,u,p;scanf("%d%d",&x,&y);m=x;n=y;while( ...

  9. C语言程序设计第五版谭浩强著 第8章291-292指针系列

    1.输入3个整数,按由小到大的顺序输出. #include<stdio.h> main() {int a,b,c,*p1,*p2,*p3;p1=&a;p2=&b;p3=&a ...

  10. C语言程序设计第五版谭浩强著 第七章部分课后习题答案

    #include<stdio.h> int gcd(int x,int y) {int z;for(;;){z=x%y;x=y;y=z;if(y==0)break;}return x; } ...

最新文章

  1. 浏览器访问网页过程中发生了什么?(转)
  2. Metasploit运行环境内存不要低于2GB
  3. Google Analytics 跟踪代码安装后状态总是显示'未安装跟踪代码'
  4. [黑马程序员二]:C#面向对象基础
  5. HTML/CSS——float制作页面DEMO
  6. 第三次学JAVA再学不好就吃翔(part77)--迭代器遍历
  7. python重命名窗口_Python:即时重命名方法名称
  8. 01-Javascript简介
  9. 一道水的不能再水的题目
  10. 一键了结CUP100%问题
  11. linux——线程通信(1)
  12. 个人生活助手app_美居App 6版重磅升级 开启智慧生活新范式
  13. android注解处理技术APT
  14. java图书管理系统源码免费_Java图书管理系统 附源码
  15. MySQL入门学习笔记
  16. 如何不授权情况下获取自己微信openid/傻瓜式获取
  17. Image Tampering Detection via Semantic Segmentation Network
  18. html背景图片被白色覆盖,html – CSS背景图片淡出白色
  19. 腾讯微博qq说说备份导出工具_软件推荐Day51 其他工具类 腾讯微博备份
  20. 社科院与杜兰大学金融管理硕士——在自己的领域努力拼搏,终将遇到专属的光芒

热门文章

  1. 个人学习笔记——庄懂的技术美术入门课(美术向)06
  2. feign Ambiguous mapping 解决方式
  3. CST — 电磁及EMC仿真工具
  4. tumblr_如何将Google AdSense添加到您的Tumblr博客
  5. 算法:凸多边形最优三角剖分
  6. sersync同步备份生产实例
  7. php太平洋时间转成北京时间,北京时间 → 太平洋时间 换算表 和太平洋时间 → 北京时间 换算表...
  8. PID参数调节的经验
  9. 手写Promise 封装Promise resolve reject then catch Promise.resolve Promise.reject
  10. 计算机电缆国家标准是什么,电线电缆国家标准-计算机电缆(电压等级:0.45/0.75KV,企标)...