使用多个类型的qsort()

时间:2013-09-16 09:37:56

标签: c

我想使用C的qsort()函数对每个具有不同类型的数组进行排序,如下所示:

int a[] = {1, 2, 3};
const char *b[] = {"foo", "bar", "bas"};
my_defined_type_t *c[100]; for (i=0; i<100; i++) { fill(c[i]); }

是否有必要为每种类型编写比较函数,如intComparator(),stringComparitor(),myDefinedTypeComparitor(),并依次对每个比较函数调用qsort,或者可以在C中完成这样的事情:

int myGrandUnifiedComparisonFunction(const void* a, const void* b) {

if *a, *b are integers: intComparatorCode;
if *a, *b are strings: stringComparitorCode;
if *a, *b are my_defined_type_t's: myDefinedTypeComparitorCode;
/* etc. */

}

5 个答案:

答案 0 :(得分:3)

需要考虑两个问题:

1)信息问题

你的比较函数获得两个void指针。这只是一些可能意味着什么的模式。 C不会将任何信息附加到例如浮点数或字符指针上,因此如果您事先不知道,则无法判断某些数据是否是其中一个。

也就是说,您可以自己附加这些信息,方法是将数据包含在一个结构中,并附上一个枚举值,告诉您内部的内容。但从技术上讲,你不会比较浮点数或char指针,而是包装浮点数和包裹的char指针。类似的东西:

enum { Float, String, MyType } typ;

typedef struct { 
    typ t;
    union {
       float f;
       char *s;
       myType mt;
    } wrappedData;

然后你可以写一个比较wrappedData *的函数。 这就是每种动态语言的作用。

然后,即使你的大统一功能仍然需要适当地比较它们,也就是说,每种类型都不同,所以你不会获得太多。相反,你可以将逻辑组合成一个并不真正属于一个的函数。

2)效率问题

虽然这可能不会打扰你,但是每次比较操作都会解开一个指针并检查它的类型,这可能会大大增加你的运行时间。

<强>结论:

你必须采取某种方式包装你的数据,这是一个可疑的优势和显着的劣势(效率)。不要这样做。

答案 1 :(得分:2)

C没有introspection,因此无法知道void*指向的是什么类型。

每种类型需要一个比较函数,并且必须使用正确的回调调用qsort

答案 2 :(得分:1)

你的想法

int myGrandUnifiedComparisonFunction(const void* a, const void* b) {

    if *a, *b are integers: intComparatorCode;
    if *a, *b are strings: stringComparitorCode;
    if *a, *b are my_defined_type_t's: myDefinedTypeComparitorCode;
   /* etc. */
}

非常好。你有没有尝试过它?

问题在于无法在C或C ++中实现它。无法确定void*指向的变量类型。

答案 3 :(得分:0)

不,你不能拥有泛型函数,因为类型现在在运行时在C中传递(与面向对象语言不同)。必须在编译时知道该类型。

因此,您需要拥有一个知道如何比较每种类型的函数并告诉qsort该函数。

答案 4 :(得分:0)

我猜你可以,如果你以某种方式神奇地知道类型,但为什么要打扰?此外,您还可以传入大小,因此您需要在2个地方进行检查。

不确定这有什么好处。