我正在尝试使用qsort对包含指针的结构进行排序。比较功能有问题吗?我该如何解决,以便可以根据抄送进行排序。
代码如下:
#include <stdlib.h>
#include <string.h>
typedef enum {
PETROL,
DIESEL,
ELECTRIC,
LPG,
BIOFUEL,
OTHER
} fuel_t;
typedef struct car_tag {
unsigned cc;
fuel_t fueltype;
} car_t;
typedef struct fleet_tag {
car_t ** cars;
size_t n_cars;
} fleet_t;
int car_comp(const void * vp1, const void * vp2) {
const car_t* const c1 = vp1;
const car_t* const c2 = vp2;
if (c1->cc > c2->cc)
return -1;
else if (c1->cc < c2->cc)
return 1;
else {
return 0;
}
}
int main() {
car_t array[] = {
{ 600, PETROL},
{1200, PETROL},
{1000, PETROL},
{1600, DIESEL},
{1000, ELECTRIC}
};
int size = sizeof(array) / sizeof(array[0]);
fleet_t fl;
fl.n_cars = size;
fl.cars = malloc(size * sizeof(car_t));
for (int i = 0; i < size; i++) {
car_t* pc = malloc(sizeof(car_t));
memcpy(pc, &array[i], sizeof(car_t));
fl.cars[i] = pc;
}
// how to sort cars by cc
qsort(&fl, fl.n_cars, sizeof(car_t), car_comp);
// sort function doesn't correctly sort fleet of cars by cc
}
答案 0 :(得分:1)
我完全没有看到在此代码 中需要为每个待分类汽车进行动态分配和memcpy调用。
您要建立一个指针床(一个指针序列),所以为什么不分配它(您在做什么),然后在其中存储array
中每个元素的地址。然后,定制比较器以处理要发送的内容:指针的地址(指向指针的指针)并相应地设置取消引用
此外,您应该将fl.cars
传递给qsort,而不是&fl
,并且其中的sizeof参数也是错误的。
最后,我不知道您是否有意在比较器中使用大于逻辑的堆栈,但这正是您最终的目的。
示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum {
PETROL,
DIESEL,
ELECTRIC,
LPG,
BIOFUEL,
OTHER
} fuel_t;
typedef struct car_tag {
unsigned cc;
fuel_t fueltype;
} car_t;
typedef struct fleet_tag {
car_t ** cars;
size_t n_cars;
} fleet_t;
int car_comp(const void * vp1, const void * vp2)
{
const car_t * const *pc1 = vp1;
const car_t * const *pc2 = vp2;
if ((*pc1)->cc > (*pc2)->cc)
return -1;
if ((*pc1)->cc < (*pc2)->cc)
return 1;
return 0;
}
int main() {
car_t array[] = {
{ 600, PETROL},
{1200, PETROL},
{1000, PETROL},
{1600, DIESEL},
{1000, ELECTRIC}
};
int size = sizeof(array) / sizeof(array[0]);
fleet_t fl;
fl.n_cars = size;
fl.cars = malloc(size * sizeof *fl.cars);
for (int i = 0; i < size; i++)
fl.cars[i] = array+i;
// how to sort cars by cc
qsort(fl.cars, fl.n_cars, sizeof *fl.cars, car_comp);
for (int i=0; i<size; ++i)
printf("%d (%u, %d)\n", i+1, fl.cars[i]->cc, fl.cars[i]->fueltype);
free(fl.cars);
return EXIT_SUCCESS;
}
输出
1 (1600, 1)
2 (1200, 0)
3 (1000, 0)
4 (1000, 2)
5 (600, 0)
qsort
的工作原理是:向其提供一系列“事物”,长度说明存在“事物”的数量,大小指示序列中每个“事物” 的大小 ,最后是一个比较器函数,该函数将在算法执行过程中馈入每个“事物”的地址。
在您的情况下,您的“事物”是指向car_t
结构的指针。实际上,
car_t
的指针。size
。因此,呼叫变为:
qsort(fl.cars, fl.n_cars, sizeof *fl.cars, car_comp);
最后,请注意原始的array
保持不变。排序仅修改了您的指针床。这可能是合乎需要的,我希望您了解它是如何工作的。