使用qsort对struct指针数组进行排序

尝试在这个结构数组上使用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 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 

它不是按部门排序,而是按反向到达时间排序。 我真的完全失去了导致这种行为的原因。

您的代码表明您实际上正在尝试对指向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; } 

这里的问题是你告诉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); } 

如果您还有任何疑问,请与我们联系

错误1

 printf("size=%d",sizeof(access_data*)); 

打印4,预期:16。这是最大的问题:排序8次4字节,而不是8次16。

怪异2

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); } 

优化3

你的compare_data()等于

 int compare_data(const void* a, const void* b){ return ((access_data*)b)->sector - ((access_data*)a)->sector; } 

我的全部工作计划:

 #include  #include  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;isector - ((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); }