使用 qsort - C 进行错误排序
Getting wrong sort with qsort - C
我正在尝试使用 qsort 函数对指向结构的指针数组进行排序,代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct hotel {
char *address;
_Bool full;
int nrooms;
};
/* compare based on the value of nrooms */
int roomcomp(const void *p1, const void *p2)
{
return (
((struct hotel *)p1)->nrooms -
((struct hotel *)p2)->nrooms
);
}
/* compare based on the alphabetic value of address */
int addcomp(const void *p1, const void *p2)
{
return strcmp(
((struct hotel *)p1)->address,
((struct hotel *)p2)->address
);
}
int main()
{
struct hotel *p1 = malloc(sizeof(struct hotel));
struct hotel *p2 = malloc(sizeof(struct hotel));
struct hotel *p3 = malloc(sizeof(struct hotel));
struct hotel *p4 = malloc(sizeof(struct hotel));
p1->address = strdup("aaaa");
p1->nrooms = 100;
p2->address = strdup("bbbb");
p2->nrooms = 200;
p3->address = strdup("cccc");
p3->nrooms = 300;
p4->address = strdup("dddd");
p4->nrooms = 400;
struct hotel *arr[] = {p1, p2, p3, p4};
size_t size = sizeof(arr) / sizeof(*arr);
for (int i = 0; i < size; i++) {
printf("address: %s - nrooms: %d\n", arr[i]->address, arr[i]->nrooms);
}
putchar('\n');
qsort(arr, size, sizeof(struct hotel *), roomcomp);
for (int i = 0; i < size; i++) {
printf("address: %s - nrooms: %d\n", arr[i]->address, arr[i]->nrooms);
}
}
这是我得到的结果:
address: aaaa - nrooms: 100
address: bbbb - nrooms: 200
address: cccc - nrooms: 300
address: dddd - nrooms: 400
address: aaaa - nrooms: 100
address: cccc - nrooms: 300
address: dddd - nrooms: 400
address: bbbb - nrooms: 200
我尝试了很多不同的方法,但我一直得到相同的结果...
当我尝试在 roomcomp
中打印 nrooms 的值时,我得到了指针值,所以如果我不得不猜测,我会说我以错误的方式进行转换...
struct hotel *arr[]
是一个指针数组,所以迭代器是指向指针的指针。
int roomcomp(const void *p1, const void *p2) {
const struct hotel *const *x = p1;
const struct hotel *const *y = p2;
return (*x)->nrooms - (*y)->nrooms;
作为 KamilCuk 答案的替代方案,您可以首先避免创建指针数组:
const size_t n_hotels = 4;
struct hotel *arr = malloc(n_hotels * sizeof(struct hotel));
arr[0].address = /* ... */;
arr[0].nrooms = /* ... */;
/* ... */
qsort(arr, n_hotels, sizeof(struct hotel), roomcomp);
现在传递给比较函数的东西将是 struct hotel *
并且您的 roomcomp
将按规定工作。
我正在尝试使用 qsort 函数对指向结构的指针数组进行排序,代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct hotel {
char *address;
_Bool full;
int nrooms;
};
/* compare based on the value of nrooms */
int roomcomp(const void *p1, const void *p2)
{
return (
((struct hotel *)p1)->nrooms -
((struct hotel *)p2)->nrooms
);
}
/* compare based on the alphabetic value of address */
int addcomp(const void *p1, const void *p2)
{
return strcmp(
((struct hotel *)p1)->address,
((struct hotel *)p2)->address
);
}
int main()
{
struct hotel *p1 = malloc(sizeof(struct hotel));
struct hotel *p2 = malloc(sizeof(struct hotel));
struct hotel *p3 = malloc(sizeof(struct hotel));
struct hotel *p4 = malloc(sizeof(struct hotel));
p1->address = strdup("aaaa");
p1->nrooms = 100;
p2->address = strdup("bbbb");
p2->nrooms = 200;
p3->address = strdup("cccc");
p3->nrooms = 300;
p4->address = strdup("dddd");
p4->nrooms = 400;
struct hotel *arr[] = {p1, p2, p3, p4};
size_t size = sizeof(arr) / sizeof(*arr);
for (int i = 0; i < size; i++) {
printf("address: %s - nrooms: %d\n", arr[i]->address, arr[i]->nrooms);
}
putchar('\n');
qsort(arr, size, sizeof(struct hotel *), roomcomp);
for (int i = 0; i < size; i++) {
printf("address: %s - nrooms: %d\n", arr[i]->address, arr[i]->nrooms);
}
}
这是我得到的结果:
address: aaaa - nrooms: 100
address: bbbb - nrooms: 200
address: cccc - nrooms: 300
address: dddd - nrooms: 400
address: aaaa - nrooms: 100
address: cccc - nrooms: 300
address: dddd - nrooms: 400
address: bbbb - nrooms: 200
我尝试了很多不同的方法,但我一直得到相同的结果...
当我尝试在 roomcomp
中打印 nrooms 的值时,我得到了指针值,所以如果我不得不猜测,我会说我以错误的方式进行转换...
struct hotel *arr[]
是一个指针数组,所以迭代器是指向指针的指针。
int roomcomp(const void *p1, const void *p2) {
const struct hotel *const *x = p1;
const struct hotel *const *y = p2;
return (*x)->nrooms - (*y)->nrooms;
作为 KamilCuk 答案的替代方案,您可以首先避免创建指针数组:
const size_t n_hotels = 4;
struct hotel *arr = malloc(n_hotels * sizeof(struct hotel));
arr[0].address = /* ... */;
arr[0].nrooms = /* ... */;
/* ... */
qsort(arr, n_hotels, sizeof(struct hotel), roomcomp);
现在传递给比较函数的东西将是 struct hotel *
并且您的 roomcomp
将按规定工作。