qsort函数回调函数返回值为0的情况

由PAT乙级1020题所引发:
https://pintia.cn/problem-sets/994805260223102976/problems/994805301562163200

这是某个人的解题代码:

#include <stdio.h>
#include <stdlib.h>
#define MAXN 1001
/*定义月饼结构体为mooncake*/
typedef struct {
	float stock;    //库存。
	float price;    //每款月饼总价。
	float each;    //每款月饼单价。
} mooncake;
int cmp ( const void *a, const void*b ) {
	mooncake c1 = *(mooncake *)a;    //将指针a强制转化为mooncake结构体类型。
	mooncake c2 = *(mooncake *)b;
	return c2.each > c1.each;    //按单价each降序返回。
}
int main(void) {
	int N, i;
	float D, total;
	mooncake cake[MAXN];
	
	scanf("%d %f", &N, &D);
	for ( i = 0; i < N; i++ )	scanf("%f", &cake[i].stock);	
	for ( i = 0; i < N; i++ )	scanf("%f", &cake[i].price);
	for ( i = 0; i < N; i++ )	cake[i].each = cake[i].price / cake[i].stock;
    /*数组名,数组大小,每个数组元素大小,比较函数*/
	qsort ( cake, N, sizeof(mooncake), cmp );    //sizeof(cake[0])也行。
	total = 0;
    /*月饼已经按单价降序排号,只需遍历*/
	for( i = 0; i < N && D > 0; i++ ) {
		if ( cake[i].stock <= D ) {    //某款月饼库存比需求量低。
			total += cake[i].price;    //这款月饼总价全部放入销售额。
			D -= cake[i].stock;    //需求量扣除这款月饼的库存。
		} else {    //某款月饼的库存满足了需求量。
			total += D * cake[i].each;    //销售额 = 需求量 * 这款月饼单价。
			D = 0;    //需求置零,退出循环。
		}
	}
	printf("%.2f\n", total);
	
	return 0;
}

参考文献:https://blog.csdn.net/YelloJesse/article/details/82431875?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

他在其中使用了qsort函数,返回值取决于c1和c2所指向结构体的成员变量each的大小关系,我看到他在回调函数最后所写的是:

return c2.each > c1.each;

我就在想,假如出现了c2.each<c1.each的情况,那么return的值就是0了,要知道C语言的关系表达式的结果只有0和1,在百度上的说法是:

如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;

那么当出现了c2.each<c1.each的情况时,qsort函数是如何保证序列中的元素还能降序排列的?
我在这里记下自己的这个问题,下面是网上找的qsort函数源码:
https://www.cnblogs.com/zpchya/p/10745643.html

事后觉得,看源码是个愚蠢的决定,因为后来我发现上面这个博客园的链接和《C标准库》第354页所提供的qsort源码竟然是两个版本,也是怪了。

其实在这种情况下,把qsort当成黑箱子,弄个测试程序,可能还更好,测试程序如下:

#include<stdio.h>
#include<stdlib.h>
#define MAXN 1001

typedef struct{
   float stock;
   float price;
   float each;
}mooncake;

int cmp(const void* a,const void* b)
{
   mooncake c1=*(mooncake*)a;
   mooncake c2=*(mooncake*)b;
   printf("%f %f\n",c1.stock,c2.stock);
   return c2.each>c1.each;
}

int main()
{
   int N;
   float D,total;
   mooncake cake[MAXN];
   
   scanf("%d %f",&N,&D);
   for(int i=0;i<N;i++)scanf("%f",&cake[i].stock);
   for(int i=0;i<N;i++)scanf("%f",&cake[i].price);
   for(int i=0;i<N;i++)cake[i].each=cake[i].price/cake[i].stock;
   for(int i=0;i<N;i++)printf("%f ",cake[i].stock);
   printf("\n");

   qsort(cake,N,sizeof(mooncake),cmp);
    
   for(int i=0;i<N;i++)printf("%f ",cake[i].stock);
   printf("\n");
   total=0;
   
   return 0;
}

测试N为3、4、5的情况下程序的输出结果,同时在回调函数里面加入printf函数,判断当前比较的是哪两个元素,在主函数调用qsort的前后各放置for循环,观察变化。
实验结果如下:
N=3:
输入

3 20
18 15 10
75 72 45

输出

18.000000 15.000000 10.000000 
15.000000 10.000000
18.000000 15.000000
18.000000 10.000000
15.000000 10.000000 18.000000 

N=4:
输入

4 20
18 15 10 12
75 72 45 57.6

输出

18.000000 15.000000 10.000000 12.000000 
18.000000 15.000000
10.000000 12.000000
15.000000 12.000000
18.000000 12.000000
18.000000 10.000000
15.000000 12.000000 10.000000 18.000000 

N=5;
输入

5 20
18 15 10 12 10
75 72 45 57.6 160

输出

18.000000 15.000000 10.000000 12.000000 16.000000 
18.000000 15.000000
12.000000 16.000000
10.000000 16.000000
10.000000 12.000000
15.000000 16.000000
15.000000 12.000000
18.000000 12.000000
18.000000 10.000000
16.000000 15.000000 12.000000 10.000000 18.000000 

其中结构体数组的结构体成员stock不要出现相同的情况,不然不好观察。由以上实验可以看出,当qsort的回调函数返回0时,如果假设所比较的两个元素留在原位保持不变,就能得到如上图所示的结果,因此,可以得出结论,当回调函数返回值为0时,qsort会让当前所比较的这两个元素暂时保持不动。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值