使用C语言中的 qsort 时出现警告

6
我写了自己的比较函数。
int cmp(const int * a,const int * b)
 {
   if (*a==*b)
   return 0;
else
  if (*a < *b)
    return -1;
else
    return 1;
}

我有我的声明

int cmp (const int * value1,const int * value2);

我正在程序中使用如下方式调用qsort函数:
qsort(currentCases,round,sizeof(int),cmp);

当我编译它时,会出现以下警告。
warning: passing argument 4 of ‘qsort’ from incompatible pointer type
/usr/include/stdlib.h:710: note: expected ‘__compar_fn_t’ but argument is of typeint
(*)(const int *, const int *)

该程序运行良好,所以我唯一的担忧是为什么它不喜欢我使用的方式?

https://dev59.com/gEvSa4cB1Zd3GeqPhtz_#2228754 - Alok Singhal
2
只是一个关于简化您的cmp实现的建议;您可以使用减法而不是if / else语句。 - nategoose
1
@nategoose:除非您想引入令人讨厌的整数溢出错误,否则不要这么做。 - R.. GitHub STOP HELPING ICE
2个回答

21

cmp函数的原型必须是:

int cmp(const void* a, const void* b);

您可以在调用qsort时进行类型转换(不建议这样做):

qsort(currentCases, round, sizeof(int), (int(*)(const void*,const void*))cmp);

或者在 cmp 函数中将 void 指针转换为 int 指针(标准做法):

int cmp(const void* pa, const void* pb) {
   int a = *(const int*)pa;
   int b = *(const int*)pb;
   ...

7
从技术上讲,第一个是未定义行为。不能保证你的实现以相同的方式传递const int*const void*调用约定。实际上,我认为这没问题。显然,GCC也这样认为,因为它只是一个警告。 - Steve Jessop
2
使用强制类型转换的方法是完全不可接受的,即使它似乎“有效”。 - AnT stands with Russia
2
@AndreyT:你还有什么建议?自己写快速排序吗?(请注意这是C语言,不是C ++,您不能使用std :: sort。) - kennytm
@AndreyT:我明白了。因为两种方法都涉及到强制类型转换 ^_^。 - kennytm
长话短说:强制转换函数指针类型 = 邪恶,强制转换其他类型 = 较少邪恶。 - Kos
显示剩余2条评论

0
根据man页面,__compar_fn_t被定义为:typedef int(*) __compar_fn_t (const void *, const void *) 您的cmp指定了int*参数。虽然它不喜欢,但只是作为警告列出。

这是因为在C语言中,void*指针可以隐式转换为任何其他类型的指针。但在C++中会有一些问题。 - Aatch
你看的是哪个 man 页?qsort 的那个没有提到 __compar_fn_t - Flimm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接