我打算每次用另一个坐标对多维点的数组进行排序。 我想使用c qsort()方法,但为了做到这一点,我必须使用比较器函数,它的输入只有两个指针,所以我不能发送它所需的坐标进行排序。 因此,我想出了两个解决方案,我正在努力选择其中最好的一个:
第一个听起来像是一个快速的解决方案,虽然它可能是循环孔,而第二个听起来像这样一个简单任务的过度杀伤。 如果遇到问题,我会很高兴听到任何更好的解决方案。
答案 0 :(得分:2)
如果您的系统有qsort_r,则可以使用它。 qsort_r有一个额外的参数,可用于传递坐标。
int comparator(const void *l, const void *r, void *param)
{
Point* lPoint = (Point*) l;
Point* rPoint = (Point*) r;
Coordinate* coord = (Coordinate*) param;
// Do your comparison ....
}
void mySort(Point* list, size_t listSize, Coordinate sortCoord)
{
qsort_r(list, listSize, sizeof(Point), comparator, &sortCoord);
}
如果您使用glibc(例如在Linux上)和OS X上,它绝对可用。但是,它不是官方可移植的。请参阅有关便携性的答案
How portable is the re-entrant qsort_r function compared to qsort?
我的代码示例是为Linux版本编写的。对于OS X,比较器必须声明为
int comparator( void *param, const void *l, const void *r)
并且qsort_r调用是
qsort_r(list, listSize, sizeof(Point), &sortCoord, comparator);
答案 1 :(得分:0)
最便携的版本可能确实是将comparsion对象(“functor”)封装在一个单独的文件中,然后使用静态文件范围变量来改变函数的行为。
something.h
void set_something (something_t s);
int compare_something (const void* obj1, const void* obj2);
something.c
#include "something.h"
static something_t someting = 0;
void set_something (something_t s)
{
something = s;
}
int compare_something (const void* obj1, const void* obj2)
{
const coord_t* c1 = obj1;
const coord_t* c2 = obj2;
// do stuff with c1, c2 based on something
}
唯一的缺点是你不能让多个线程同时执行不同类型的排序,但这不太可能是一个问题。 (如果是,设计某种方式将“something”变量作为参数传递给每个线程回调。)
答案 2 :(得分:0)
我建议选择#3
C11显示qsort_s()
,它提供了所需的 context 参数。这是在附件K(规范)中,因此可能不包含在符合C11的编译器中。
此功能的可用性可能不大。
K.3.6.3.2 qsort_s函数
errno_t qsort_s(void *base, rsize_t nmemb, rsize_t size,
int (*compar)(const void *x, const void *y,
void *context), void *context);
...比较函数的第三个参数是 传递给
context
的{{1}}参数。qsort_s
context
的唯一用途是将其传递给比较函数
如果此功能不可用,请考虑模仿此界面的替代方案。