【问题标题】:Implement comparator for qsort. How to get rid of this warning?为 qsort 实现比较器。如何摆脱这个警告?
【发布时间】:2018-07-06 12:31:33
【问题描述】:

我想知道如何摆脱以下警告:

   kwic1.c:118:48: warning: incompatible pointer types passing 'int (const char *,
  const char *)' to parameter of type 'int (* _Nonnull)(const void *, const
  void *)' [-Wincompatible-pointer-types]

我正在为 qsort 实现一个比较器。这是我的功能

 int comparator(const char *p, const char *q)
 {
   int index_p = 0;
   int index_q = 0;

    while(p[index_p] != '\0')
    {
      if(isupper(p[index_p]))
         break;
     index_p++;
    }
   ...

我尝试过投射pq,但没有成功。

【问题讨论】:

  • 这行得通吗?要么您正在对字符数组而不是指向数组的指针进行排序 - 这非常低效 - 或者您的 pq 应该是 const char **
  • 如果您正在对字符串中的字符进行排序(所以"abracadabra" 将变为"aaaaabbcdrr"),您将不会单步执行字符串(您只需比较参数点的两个字符在)。如果要对字符串进行排序,则会传递两个 const char ** 值,而不是 const char * 值。无论哪种方式,都存在比函数参数类型更多的问题。

标签: c function-pointers qsort


【解决方案1】:

在你的函数中使用(隐式)指针类型转换:

int comparator(const void *p1, const void *q1){
    const char *p = p1, *q = q1;
    // The rest of the code requires no change

函数原型在作为函数指针传递时完全匹配很重要。即,您不能将int (*)(const char*, const char*) 函数指针传递给int (*)(const void*, const void*) 的参数。您应该做的就是在比较函数中将指针转换为所需的类型。

【讨论】:

  • @YipingWang 我把参数名从p, q改成了p1, q1
  • 你可以放弃演员表。在 C 中,不必从void-pointers 转换。
  • const char *p = p1, *q = q1; 完全可以。
  • @alk 是的。我忘记了。谢谢。
【解决方案2】:

Qsort 在 C 中是一个真正的通用函数,但它会让人绊倒,因为类型很重要

比较器的参数应该是(const void*)

如果您对int 进行排序,那么您可以简单地转换为(const int*)
void 已替换为 int。)

但您似乎正在对(char*)s 进行排序。因此,您需要记住正确地转换那个额外的间接:(const void*)(const (char*)*)(const char**)
void 已替换为 char*。)

我不确定你想用你提供的比较器 sn-p 来完成什么,但是 Here is an example of qsort()ing c-strings.

【讨论】:

  • 我很确定while(p[index_p] != '\0') 排序后的daya 是char 类型。
  • @iBug 你在混合类型。对于您的代码示例,pchar*,这使得 p1 成为 const char** 的别名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
  • 2022-11-16
  • 2020-08-25
  • 1970-01-01
  • 2019-07-27
相关资源
最近更新 更多