像qsort这样的C函数如何处理不同的数据类型?

像qsort这样的C函数如何处理不同的数据类型?,c,generics,void-pointers,C,Generics,Void Pointers,在stdlib.h中,有一个函数qsort()与prototype的声明: void qsort( void *ptr, size_t count, size_t size, int (*comp)(const void *, const void *) ); 显然,这是一个泛型编程。 我想知道它是如何实现的,如何从void*类型中获取元素?void*指针是根据size\u t size(代码>qsort中的第三个参数)来进行的 首先,我们将void*键入char*,然后根据大

在stdlib.h中,有一个函数qsort()与prototype的声明:

void qsort( void *ptr, size_t count, size_t size,
        int (*comp)(const void *, const void *) );
显然,这是一个泛型编程。
我想知道它是如何实现的,如何从void*类型中获取元素?

void*
指针是根据
size\u t size
(代码>qsort中的第三个参数)来进行的

首先,我们将
void*
键入
char*
,然后根据
大小执行指针算术(因为char需要
1
字节,所以添加大小将给出正确的指针算术)

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

e、 g


注意:大小由实现定义,因此它可能因编译器而异。最后一个参数是函数指针。正如你所暗示的,你一定在某处实现了这个函数。 但当您实现它时,您确实知道指针之王实际上是您的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 */
}
#包括
空区将空区与空区进行比较(空区*ptr,尺寸,
大小大小,整数(*cmp)(常数无效*,常数无效*){
未签名的i;
对于(i=1;i0)
printf(“第一个元素大于%u\n”处的元素,i);
其他的
printf(“第一个元素等于%u\n”,i)处的元素;
}
}
int icmp(常数无效*x,常数无效*y){
返回*(int*)x-*(int*)y;
}
int main()
{
int x[]={5,3,6,2,4,8,-1,10};
比较第一个和第二个(x,8,sizeof(int),icmp);
}

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

是的,我想知道的是具体的过程。例如,如何获取ptr中的第三个元素?请注意:这个问题不是关于如何使用qsort(),而是关于qsort如何在内部计算元素在空间中的位置*
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
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 */
}
#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);
}