Qsort这样的C函数如何使用不同的数据类型?

时间:2012-11-21 08:25:25

标签: c generics void-pointers

stdlib.h中,函数qsort()的声明包含原型:

void qsort( void *ptr, size_t count, size_t size,
        int (*comp)(const void *, const void *) );

显然这是一个通用编程。 我想知道它是如何实现的,如何从void * type中获取元素?

3 个答案:

答案 0 :(得分:2)

void *指针根据size_t sizeqsort中的第3个参数)进行投放

首先我们将void*类型转换为char*然后根据size进行指针运算(因为char需要1个字节,因此添加大小将给出正确的指针算法)

编辑:(适用于内置数据类型)

char *ptr = (char*)vp; //here vp is void *p

*(ptr + (n-1)*size); //will give you nth element 

e.g。

size =1 and want 3rd element it means it will give you 3rd char
size =4 and want 3rd element it means it will give you 3rd int or float
size =2 and want 3rd element it means it will give you 3rd short int
size =8 and want 3rd element it means it will give you 3rd double

注意:size是实现定义的,因此可能因编译器而异

答案 1 :(得分:1)

#include <stdio.h>

void compare_first_to_rest(void *ptr, size_t nelem, 
   size_t size, int (*cmp)(const void*, const void*)) {
    unsigned i;
    for(i = 1; i < nelem; ++i)
        {
        int res = cmp(ptr, (char*)ptr + i * size);
        if(res < 0)
            printf("First element is less than element at %u\n", i);
        else if(res > 0)
            printf("First element is greater than element at %u\n", i);
        else
            printf("First element is equal to element at %u\n", i);
        }
}

int icmp(const void *x, const void *y) {
   return *(int*)x - *(int*)y;
}

int main()
{
   int x[] = { 5, 3, 6, 2, 4, 8, -1, 10 };
   compare_first_to_rest(x, 8, sizeof(int), icmp);
}

正如您所看到的,`compare_first_to_rest'不知道它在第一个参数中接收的元素的类型。但是知道每一个的大小,它可以获得指向它们中的每一个的指针,并让函数指针完成工作。

答案 2 :(得分:0)

最后一个参数是一个函数指针。正如你暗示的那样你必须在某个地方实现这个功能。 但是当你实现它时,你确实知道指针之王实际上是你的void *元素。

在你的comp函数中,你必须将2个参数转换为你想要使用的指针类型,如下所示:

int myCompFn(const void * e1, const void * e2)
{
    MyType *elem1=(MyType*)e1;
    MyType *elem2=(MyType*)e2;
    ... /* then compare elem1 and elem2 regarding to there definition */
}