在C中使用空指针对任何类型的元素进行排序

在C中使用空指针对任何类型的元素进行排序,c,sorting,void-pointers,C,Sorting,Void Pointers,大家好,我正在编写一个程序,用于对C中的常规元素进行排序。它可以对任何类型的对象(int、float、复数、对象)进行排序 我想到的是使用空指针 void qsort(void *ptr,int sz,int i,int j,int (*fptr) (const void *,const void *) ) { if(i<j) { int p=(i+j)/2; p=partition(ptr,sz,i,j,p,fptr); qsort(ptr,size,i,p-1

大家好,我正在编写一个程序,用于对C中的常规元素进行排序。它可以对任何类型的对象(int、float、复数、对象)进行排序

我想到的是使用空指针

void qsort(void *ptr,int sz,int i,int j,int (*fptr) (const void *,const void *) )
{

if(i<j)
{
    int p=(i+j)/2;
    p=partition(ptr,sz,i,j,p,fptr);
    qsort(ptr,size,i,p-1,fptr); 
    qsort(ptr,size,p+1,j,fptr); 
}
} 
用于交换两个元素

void swap(void *a,void *b,int sz)//for swapping
{
     if(sz==0)
     { 
      void *c;
      c=a;
      a=b;
      b=c;
      }
     else if(sz==1)
      {
      a=(int*)a;
      b=(int*)b;
      int c;
      c= *a;
      *a=*b;
      *b=c;
       }

     else if(sz==2)
     {
       a=(float*)a;
       b=(float*)b;
       float c;
       c= *a;
       *a=*b;
       *b=c;
     }
编辑

qsort(arr、4、0、9和比较)

完整的代码正在构建中,请告诉我我的方法中是否有一些优化,或者对于这个问题是否有一些更好的替代方案。 在我看来,它真的会很大


许多thanx提前

问题在于,这不允许对自定义类型(如结构)进行排序。通常的方法是接受一个函数指针,您可以调用它来进行比较。

问题是,这不允许对自定义类型(如结构)进行排序。通常的方法是接受一个函数指针,您调用它来进行比较。

您应该做的是将比较作为函数指针传入。您正在传入一个函数指针,但似乎没有使用它来比较值。您不必预定义所有的比较,因为您可以在使用它们时根据所使用的值类型来定义它们。

您应该做的是将比较作为函数指针传入。您正在传入一个函数指针,但似乎没有使用它来比较值。您不必预定义所有的比较,因为您可以在使用它们时为您使用的值类型定义它们。

由于您的交换例程可能会被
分区
函数使用,因此它应该处理任意大小的对象,而不仅仅是您计划传递给代码的对象

void swap (void *a, void *b, int sz) {
    char buf[512];
    void *p = buf;
    if (sz > sizeof(buf)) p = malloc(sz);
    memcpy(p, a, sz);
    memcpy(a, b, sz);
    memcpy(b, p, sz);
    if (p != buf) free(p);
}
从编写比较例程的方式来看,您似乎只计划发送某些类型的数组。但是,
sz
通常用于告诉数组中的单个元素有多大,而不是作为类型标识符,因为您似乎正在尝试使用它

struct x { int key; /*...*/ };

int cmp_x (const void *a, const void *b) {
    const struct x *xa = a;
    const struct x *xb = b;
    return (xa->key > xb->key) - (xa->key < xb->key);
}

struct x array_x[100];
/* populate array */
qsort(array_x, sizeof(struct x), 0, 100, cmp_x);

由于您的交换例程可能会被
分区
函数使用,因此它应该处理任意大小的对象,而不仅仅是您计划传递给代码的对象

void swap (void *a, void *b, int sz) {
    char buf[512];
    void *p = buf;
    if (sz > sizeof(buf)) p = malloc(sz);
    memcpy(p, a, sz);
    memcpy(a, b, sz);
    memcpy(b, p, sz);
    if (p != buf) free(p);
}
从编写比较例程的方式来看,您似乎只计划发送某些类型的数组。但是,
sz
通常用于告诉数组中的单个元素有多大,而不是作为类型标识符,因为您似乎正在尝试使用它

struct x { int key; /*...*/ };

int cmp_x (const void *a, const void *b) {
    const struct x *xa = a;
    const struct x *xb = b;
    return (xa->key > xb->key) - (xa->key < xb->key);
}

struct x array_x[100];
/* populate array */
qsort(array_x, sizeof(struct x), 0, 100, cmp_x);


你有理由不只是使用通常的qsort函数吗?我不担心大小,但枚举会使代码更具可读性。顺便说一句,你在swap()中的方法行不通:特别是,当你第一次说“a=(int*)a”然后说“a=*b”时,对于第二个语句,a和b不再是int。从风格上来说,你可以使用switch语句,而不是长链的ifs。我用
int
array的一个例子更新了我的答案。想法是一样的,调用者会传递一个不同的比较函数,一个特定于他们数组的比较函数。是的,这样更好,因为你不知道他们想要排序什么疯狂的数组类型。你有理由不使用通常的qsort函数吗?我不担心大小,但枚举会使代码更具可读性。顺便说一句,你在swap()中的方法行不通:特别是,当你第一次说“a=(int*)a”然后说“a=*b”时,对于第二个语句,a和b不再是int。从风格上来说,你可以使用switch语句,而不是长链的ifs。我用
int
array的一个例子更新了我的答案。想法是一样的,调用者会传递一个不同的比较函数,一个特定于他们数组的比较函数。是的,这样更好,因为你不知道他们想要排序什么疯狂的数组类型。我想你会发现这就是
fptr
参数的作用。但是你是对的,它永远不会进入比较函数,所以有些奇怪的事情发生了。我想你会发现这就是
fptr
参数的作用。但是你是对的,它永远不会进入比较函数,所以有些奇怪的事情发生了。那么我们将如何比较不同的类型你为什么要比较不同的类型?如果您正在排序,则您的排序类型相同。您不会传入
文件*
字符*
并对它们进行排序。哪个更大?这根本没有道理。您将传入一组
int
s或一组
double
s或一组
char
s。通过不同的类型,我的意思是对char、int等进行排序,但您(可能)不想同时对
char
s和
int
s进行排序。如果你这样做了,你应该在传递它们之前将它们转换为另一个,否则你将无法在
qsort
函数中对它们进行迭代。那么我们将如何比较不同的类型你会比较不同的类型吗?如果您正在排序,则您的排序类型相同。您不会传入
文件*
字符*
并对它们进行排序。哪个更大?这根本没有道理。您将传入一组
int
s或一组
double
s或一组
char
s。通过不同的类型,我的意思是对char、int等进行排序,但您(可能)不想同时对
char
s和
int
s进行排序。如果这样做,则应在传入它们之前将它们转换为另一个,否则将无法在
qsort
函数中对它们进行迭代。