【发布时间】:2021-07-28 20:04:50
【问题描述】:
我有一个这样的结构数组
typedef union value_
{
double d;
int i;
} value;
typedef struct number_
{
char type;
value val;
}number;
类型可以是'i' 或'd',取决于存储在联合字段中的整数或双精度值。
数组如下所示:
Integer value: -3
Double value: 4.84
Integer value: -4
Double value: 1.65
Integer value: 1
Double value: 2.54
Integer value: 2
Double value: -0.09
主要的是整数和双精度数一一对应。我需要使用 qsort 以下列方式对这个数组进行排序:整数应该从低到高排序,反之亦然。 我使用以下函数进行比较:
int compare(const void *A, const void *B){
number *a = (number*)A;
number *b = (number*)B;
if (a->type == b->type) {
if (a->type =='i') {
return a->val.i - b->val.i;
} else {
if (a->val.d > b->val.d) return -1;
if (a->val.d < b->val.d) return 1;
else return 0;
}
} else {
return 0;
}
}
假设,如果联合中的值有不同的类型,则返回0而不进行比较,因此应该保存int,double,int,double这样的序列。但结果如下:
Integer value: -1
Integer value: -5
Double value: 0.20
Integer value: 2
Double value: -0.04
Double value: -2.69
Integer value: 4
Integer value: 5
Double value: 2.04
Integer value: 3
如果在这种情况下应该返回 0,为什么它会用整数更改双精度数?
【问题讨论】:
-
由于您的
compare函数为两种不同类型返回equal,因此最终结果将是不可预测的。您可以更改它,使所有整数都低于所有双精度值,反之亦然。 -
谢谢,我怀疑,这样比较是个坏主意
-
我不认为你可以使用标准的
qsort函数来做你想做的事。如果您的compare函数针对不同的类型返回0,那么正如@500-InternalServerError 所指出的那样,您有不可预测/未定义的行为;但是,如果您返回+1或-1,则int和double类型将被打乱,以便它们在列表中是连续的,不是以他们最初的“交错”顺序。你需要自己的排序函数。 -
将
typedef struct number_更改为typedef struct number。没有理由添加下划线。 -
来自 qsort 手册页:“如果两个成员比较相等,则它们在排序数组中的顺序未定义。”。我不认为您想要什么,您需要在结构中添加信息(数组中的结构位置)或使用其他排序函数来保留顺序