我在尝试对这个结构数组使用qsort时得到了奇怪的结果。
我有这个结构:
struct access_data{
int sector;
int arrival_time;
int checked;
int processed;
};
我从一个文件构造一个access_data指针数组,使它们按到达时间排序,但我需要稍后按扇区对它们进行排序,所以我有以下内容:
int compare_data(const void* a, const void* b){
if (((access_data*)a)->sector < ((access_data*)b)->sector)
return 1;
else if (((access_data*)a)->sector > ((access_data*)b)->sector)
return -1;
else
return 0;
}
void scan(access_data* data[], int len, int sec_to_sec_seek){
qsort(data, len, sizeof(access_data*), &compare_data);
show_data(data, len);
}
show_data只是打印数据,但我在示例输入上得到以下内容;再次,按到达时间排序:
data[0]: arrival_time: 7, sector: 3
data[1]: arrival_time: 6, sector: 8
data[2]: arrival_time: 5, sector: 6
data[3]: arrival_time: 4, sector: 5
data[4]: arrival_time: 3, sector: 12
data[5]: arrival_time: 2, sector: 10
data[6]: arrival_time: 1, sector: 1
data[7]: arrival_time: 0, sector: 2
根本不按行业排序,而是按逆向到达时间排序。我真的完全失去了导致这种行为的原因。
答案 0 :(得分:17)
您的代码表明您实际上正在尝试对指向struct的指针数组进行排序。
在这种情况下,您缺少一个间接级别。你也可以改变你的指示。
您的compare_data例程适用于对结构数组进行反向排序,但您希望根据它们指向的内容对指针数组进行排序。
int compare_pointed_to_data(const void* a, const void* b) {
// a is a pointer into the array of pointers
struct access_data *ptr_to_left_struct = *(access_data**)a;
struct access_data *ptr_to_right_struct = *(access_data**)b;
if ( ptr_to_left_struct->sector < ptr_to_right_struct->sector)
return -1;
else if (ptr_to_left_struct->sector > ptr_to_right_struct->sector)
return 1;
else
return 0;
}
答案 1 :(得分:0)
这里的问题是你告诉QSort对一个指针数组进行排序,因此比较器中的参数是指针的指针。
int compare_data(const void* _a, const void* _b){
access_data *a = *(access_data**)_a, *b = *(access_data**)_b;
if ((a)->sector < (b)->sector)
return 1;
else if ((a)->sector > (b)->sector)
return -1;
else
return 0;
}
void scan(access_data* data[], int len, int sec_to_sec_seek){
qsort(data, len, sizeof(access_data*), &compare_data);
show_data(data, len);
}
如果您还有任何问题,请告诉我
答案 2 :(得分:0)
printf("size=%d",sizeof(access_data*));
打印4,预期:16。这是最大的问题:排序8次4字节,而不是8次16次。
qsort()期望指向数据的指针,但scan()接收指向数据的指针。推荐修复:
void scan(access_data data[], int len, int sec_to_sec_seek){
qsort(data, len, sizeof(access_data), &compare_data);
show_data(data, len);
}
您的compare_data()
等于
int compare_data(const void* a, const void* b){
return ((access_data*)b)->sector - ((access_data*)a)->sector;
}
我的完整工作计划:
#include <stdio.h>
#include <stdlib.h>
struct access_data {
int sector;
int arrival_time;
int checked;
int processed;
};
typedef struct access_data access_data;
void show_data(access_data*data, int len) {
printf("Showing size=%d",sizeof(access_data*));
for(int i=0;i<len;i++) {printf("data[%d]: arrival_time: %d, sector: %d\n",i,data[i].arrival_time,data[i].sector);}
}
int compare_data(const void* a, const void* b){
return ((access_data*)b)->sector - ((access_data*)a)->sector;
}
int compare_data1(const void* a, const void* b){
if (((access_data*)a)->sector < ((access_data*)b)->sector)
return 1;
else if (((access_data*)a)->sector > ((access_data*)b)->sector)
return -1;
else
return 0;
}
void scan(access_data data[], int len, int sec_to_sec_seek){
qsort(data, len, sizeof(access_data), &compare_data);
show_data(data, len);
}
int main() {
printf("START\n");
access_data data[8]={
{3,4,5,6},
{2,1,5,5},
{1,1,3,6},
{4,4,5,4},
{5,4,3,4},
{6,2,5,6},
{7,2,5,4},
{0,4,5,6}
};
scan(data,8, 0);
}