在C中使用空指针对任何类型的元素进行排序
大家好,我正在编写一个程序,用于对C中的常规元素进行排序。它可以对任何类型的对象(int、float、复数、对象)进行排序 我想到的是使用空指针在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
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
函数中对它们进行迭代。