C语言程序与设计第四版课后习题 - 第八章(一)
8.1 指针由小到大的顺序输出
题目概述:
输入 3 个整数,按由小到大的顺序输出
题目思路:
本题只需要两两比较两个数的大小,需要用指针来完成,我们定义三个指针变量,存放三个变量的地址,用指针解引用之后比较然后排序即可
比较的思路是:
- 两两进行比较,
- 先让pmin和pmid进行比较,把较小的值的地址存放到pmin中
- 再让pmin和pmax进行比较,把较小的值的地址还是存放在pmin中
- 此时已经比较完最小值
- 然后再让pmid和pmax进行比较,把次小的值存放到pmid中
- 之所以直接改变指针指向,是因为只改变指针指向不需要进行传值,这样效率更高,这个优势会在第二题有所体现
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{int a = 0;int b = 0;int c = 0;int* pmin = &a;int* pmid = &b;int* pmax = &c;int* temp = NULL;scanf("%d %d %d", &a, &b, &c);if (*pmin > *pmid){temp = pmin;pmin = pmid;pmid = temp;}if (*pmin > *pmax){temp = pmin;pmin = pmax;pmax = temp;}if (*pmid > *pmax){temp = pmid;pmid = pmax;pmax = temp;}printf("%d %d %d", *pmin, *pmid, *pmax);return 0;
}
运行结果如下:
8.2 输入 3 个字符串,按由小到大的顺序输出
题目概述:
输入 3 个字符串,按由小到大的顺序输出
题目思路:
本题是按照首字符大小进行排序输出
- 做这题首先要回顾两种字符函数
- strcmp函数
- 函数原型:int strcmp(char * s1, char *s2)
- 返回:s1如果比s2大则返回大于0的数,相等返回等于0,s1如果比s2小则返回小于0的数
- 注意,比较的是首字符的大小
- strcmp函数
- 做法与8.1类似
- 首先要明白一点,字符串的本质就是字符数组,所以我们直接定义一个字符数组用来存放字符串
- 因为字符串不能直接进行比较,所以我们要用一个strcmp来进行两两比较
- 先让pmin和pmid进行比较,把较小的值的地址存放到pmin中
- 再让pmin和pmax进行比较,把较小的值的地址还是存放在pmin中
- 此时已经比较完最小值
- 然后再让pmid和pmax进行比较,把次小的值存放到pmid中
- 直接改变指针的指向的好处是,如果字符串很长很长,如果用中间变量的方法来进行交换的话,这样效率就特别低了,但是如果值改变指针的指向,是不需要交换的,效率自然高了
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{char s1[100] = { 0 };char s2[100] = { 0 };char s3[100] = { 0 };gets(s1);gets(s2);gets(s3);char* temp = NULL;char* pmin = s1;char* pmid = s2;char* pmax = s3;if (strcmp(pmin, pmid) > 0){temp = pmin;pmin = pmid;pmid = temp;}if (strcmp(pmin, pmax) > 0){temp = pmin;pmin = pmax;pmax = temp;}if (strcmp(pmid, pmax) > 0){temp = pmid;pmid = pmax;pmax = temp;}printf("%s\n", pmin);printf("%s\n", pmid);printf("%s\n", pmax);return 0;
}
运行结果如下:
8.3 整数互换
题目概述:
输入 10 个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数:
(1) 输人 10 个数;
(2) 进行处理;
(3)输出 10 个数
题目思路:
-
首先先处理输入函数
- 只需要注意,数组名(arr)就是首元素(&arr[0])的地址,地址的加减是以指针指向的元素为大小进行偏移,比如说arr+1,表示的是数组第一个元素的地址,等价于&arr[1]
- 我们在输入的时候,因为数组名自己就是地址,所以我们不需要再加&
-
然后优先处理输出函数(因为最后的最难,放在最后解决)
- 只需要注意,因为输出的是一个整数,而arr+i是地址,是整型指针,所以我们需要解引用,才能访问到指针指向的那个值
-
最后处理交换
-
题目要求其中最小的数与第一个数对换,把最大的数与最后一个数对换
- 只需要定义一个pmin的指针变量和pmax的指针变量,并将他们初始化为首元素的地址,那么让他们一 一进行比较,循环结束后,pmin指针所指的就是最小的数,pmax指针所指的就是最大的数
- 然后进行互换,定义一个中间变量temp,要交换值就要解引用pmin和pmax得到他们的值
- 然后一 一互换即可
-
但是可能会出现一个问题,假如首元素地址就是最大值,即max就是arr的时候,那么在进行最小值的互换时,会把max的值给互换掉,此时max指向的arr[0]就不是最大值了,所以会导致最大值没有成功排序。如下图

-
进行pmin的交换后如下图:

-
然后再进行pmax交换

最终的运行结果为:
-
解决办法:将pmin传给pmax,如下图

-
执行完pmin和第一个数交换后,就会把最大值交换到pmin和pmax所指向的地址

- 这样子就能把pmax进行交换了,不会发生错误
-
-
-
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void input(int* arr, int sz)
{int i = 0;for (i = 0; i < sz; i++){scanf("%d", (arr + i));}
}void handle(int* arr, int sz)
{int i = 0;int* pmin = arr;int* pmax = arr;for (i = 0; i < sz; i++){if (*(arr + i) < *pmin){pmin = arr + i;}if (*(arr + i) > *pmax){pmax = arr + i;}}if (pmax == arr){pmax = pmin;}int temp = 0;temp = *pmin;*pmin = *arr;*arr = temp;temp = *pmax;*pmax = *(arr + sz - 1);*(arr + sz - 1) = temp;
}void output(int* arr, int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", *(arr + i));}
}
int main()
{int arr[10] = { 0 };int sz = sizeof(arr) / sizeof(arr[0]);input(arr, sz);handle(arr, sz);output(arr, sz);return 0;
}
运行结果如下: