qsort-C 标准 library-how 发送带有非 const 参数的比较函数?
qsort-C standard library-how to send a compare function with non const args?
我正在做家庭作业。
我需要根据工作人员创建的 header 实施通用列表。
他们在 header 中定义了这样的比较函数:
typedef int(*CompareListElements)(ListElement, ListElement);
(ListElement=void*)
我正在尝试使用标准库中的 qsort,但我无法编译程序,因为我试图传递给 qsort
的比较函数正在获取非 const 参数。
有没有办法通过它呢?
先谢谢了。
我正在尝试实现的功能:
ListResult listSort(List list, CompareListElements compareElement) {
CHECK_RETURN(((list == NULL)||(compareElement == NULL)),LIST_NULL_ARGUMENT);
int size=0;
ListElement* elementArray=listToArray(list, &size);
CHECK_RETURN((elementArray == NULL), LIST_OUT_OF_MEMORY);
qsort(elementArray, size, sizeof(*elementArray), compareElement);
returnArrayToList(list,elementArray);
return LIST_SUCCESS;
}
错误:
从不兼容的指针类型
传递 'qsort' 的参数 4
此示例说明如何使用 compare()
中为 qsort
提供的参数。它将 const void*
指针转换为您正在比较的类型。请注意,我可以返回两个数字之间的简单差异,但在某些情况下,当差异 "wraps".
时可能会导致未定义的行为
你对你的链表说得很少,所以我坚持问题的标题,关于qsort()
。使用 const
指针的原因是为了防止您的 compare()
函数直接更改数据:它 returns 一个基于读取数据值的值。显然数据本身不能const
否则qsort()
将无法操作它。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRSIZE 10
struct numarr {
int numb;
struct numarr *next;
};
struct numarr array [ARRSIZE];
int compare( const void *arg1, const void *arg2 )
{
if (((struct numarr*)arg1)->numb > ((struct numarr*)arg2)->numb)
return 1;
if (((struct numarr*)arg1)->numb < ((struct numarr*)arg2)->numb)
return -1;
return 0;
}
int main() {
int i;
srand((unsigned)time(NULL));
// set up a random array
printf ("Unsorted: ");
for(i=0; i<ARRSIZE; i++){
array[i].numb = rand() % ARRSIZE;
printf ("%d ", array[i].numb);
}
printf ("%\n");
// sort and print the array
qsort (array, ARRSIZE, sizeof(struct numarr), compare);
printf ("Sorted: ");
for(i=0; i<ARRSIZE; i++){
printf ("%d ", array[i].numb);
}
printf ("%\n");
return 0;
}
程序输出
Unsorted: 8 7 3 0 7 5 9 2 0 0
Sorted: 0 0 0 2 3 5 7 7 8 9
the compare function I am trying to use qsort from the standard library
不好,尽量避免这种情况:
只需将比较函数封装到编译器接受的另一个函数中,然后传递给 qsort()
。
在包装纸内,您可以使用 Casting-Hammer 来装东西……;-)
#include <stdlib.h>
typedef void* ListElement;
typedef int(*CompareListElements)(ListElement, ListElement);
CompareListElements c = ... /* Initialise properly here. */
int cmp(const void * pv1, const void * pv2)
{
return c((ListElement)pv1, (ListElement)pv2); /* Hammering here ... */
}
int main(void)
{
int a[4] = {3, 0, 2, 1};
qsort(a, sizeof *a, 4, cmp);
}
参考您提供 listSort()
实现的编辑,您仍然可以通过使用 GNU 扩展函数 qsort_r()
:
使用我在上面提出的解决方法
int cmp_r(const void * pv1, const void * pv2, void * pv)
{
CompareListElements c_r = pv;
return c_r((ListElement)pv1, (ListElement)pv2); /* Still hammering here ... */
}
ListResult listSort(List list, CompareListElements compareElement)
{
...
qsort_r(elementArray, size, sizeof(*elementArray), cmp_r, compareElement);
...
}
我正在做家庭作业。 我需要根据工作人员创建的 header 实施通用列表。 他们在 header 中定义了这样的比较函数:
typedef int(*CompareListElements)(ListElement, ListElement);
(ListElement=void*)
我正在尝试使用标准库中的 qsort,但我无法编译程序,因为我试图传递给 qsort
的比较函数正在获取非 const 参数。
有没有办法通过它呢?
先谢谢了。
我正在尝试实现的功能:
ListResult listSort(List list, CompareListElements compareElement) {
CHECK_RETURN(((list == NULL)||(compareElement == NULL)),LIST_NULL_ARGUMENT);
int size=0;
ListElement* elementArray=listToArray(list, &size);
CHECK_RETURN((elementArray == NULL), LIST_OUT_OF_MEMORY);
qsort(elementArray, size, sizeof(*elementArray), compareElement);
returnArrayToList(list,elementArray);
return LIST_SUCCESS;
}
错误: 从不兼容的指针类型
传递 'qsort' 的参数 4此示例说明如何使用 compare()
中为 qsort
提供的参数。它将 const void*
指针转换为您正在比较的类型。请注意,我可以返回两个数字之间的简单差异,但在某些情况下,当差异 "wraps".
你对你的链表说得很少,所以我坚持问题的标题,关于qsort()
。使用 const
指针的原因是为了防止您的 compare()
函数直接更改数据:它 returns 一个基于读取数据值的值。显然数据本身不能const
否则qsort()
将无法操作它。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRSIZE 10
struct numarr {
int numb;
struct numarr *next;
};
struct numarr array [ARRSIZE];
int compare( const void *arg1, const void *arg2 )
{
if (((struct numarr*)arg1)->numb > ((struct numarr*)arg2)->numb)
return 1;
if (((struct numarr*)arg1)->numb < ((struct numarr*)arg2)->numb)
return -1;
return 0;
}
int main() {
int i;
srand((unsigned)time(NULL));
// set up a random array
printf ("Unsorted: ");
for(i=0; i<ARRSIZE; i++){
array[i].numb = rand() % ARRSIZE;
printf ("%d ", array[i].numb);
}
printf ("%\n");
// sort and print the array
qsort (array, ARRSIZE, sizeof(struct numarr), compare);
printf ("Sorted: ");
for(i=0; i<ARRSIZE; i++){
printf ("%d ", array[i].numb);
}
printf ("%\n");
return 0;
}
程序输出
Unsorted: 8 7 3 0 7 5 9 2 0 0
Sorted: 0 0 0 2 3 5 7 7 8 9
the compare function I am trying to use qsort from the standard library
不好,尽量避免这种情况:
只需将比较函数封装到编译器接受的另一个函数中,然后传递给 qsort()
。
在包装纸内,您可以使用 Casting-Hammer 来装东西……;-)
#include <stdlib.h>
typedef void* ListElement;
typedef int(*CompareListElements)(ListElement, ListElement);
CompareListElements c = ... /* Initialise properly here. */
int cmp(const void * pv1, const void * pv2)
{
return c((ListElement)pv1, (ListElement)pv2); /* Hammering here ... */
}
int main(void)
{
int a[4] = {3, 0, 2, 1};
qsort(a, sizeof *a, 4, cmp);
}
参考您提供 listSort()
实现的编辑,您仍然可以通过使用 GNU 扩展函数 qsort_r()
:
int cmp_r(const void * pv1, const void * pv2, void * pv)
{
CompareListElements c_r = pv;
return c_r((ListElement)pv1, (ListElement)pv2); /* Still hammering here ... */
}
ListResult listSort(List list, CompareListElements compareElement)
{
...
qsort_r(elementArray, size, sizeof(*elementArray), cmp_r, compareElement);
...
}