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的数
        • 注意,比较的是首字符的大小
  • 做法与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;
}

运行结果如下:
在这里插入图片描述

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值