【问题标题】:How to pass a comparator to a C function?如何将比较器传递给 C 函数?
【发布时间】:2020-09-15 05:33:42
【问题描述】:

bool (*comparator)(void *, void *) 是什么?

我正在尝试使用库中的这个函数,但我不明白它的签名。
该函数似乎期望某种标准来对列表进行排序(我认为是 SQL 中的 ASC 或 DESC),作为一个高阶函数。

void list_sort(t_list *self, bool (*comparator)(void *, void *)) {
    int unsorted_elements = self->elements_count;
    if(unsorted_elements < 2) {
        return;
    }
    t_link_element *aux = NULL;
    bool sorted = true;
    do {
        t_link_element *previous_element = self->head, *cursor = previous_element->next;
        sorted = true;
        int index = 0, last_changed = unsorted_elements;
        while(index < unsorted_elements && cursor != NULL) {
            if(!comparator(previous_element->data, cursor->data)) {
               aux = cursor->data;
               cursor->data = previous_element->data;
               previous_element->data = aux;
               last_changed = index;
               sorted = false;
            }
            previous_element = cursor;
            cursor = cursor->next;
            index++;
        }
        unsorted_elements = last_changed;
    } while(!sorted);
}

函数的最后定义在commons/collections/list.h
经过多次尝试,我无法弄清楚如何正确使用此功能。

#include <stdio.h>
#include <stdlib.h>
#include <commons/collections/list.h>

/*I added this function thanks to the help of the community, 
*and now it works, the list is printed backwards now.*/

bool comparator(void * a, void * b) { 
    return (int*) a > (int*) b;
}    

int main()
{
    t_list *list = list_create();
    int add[] = {4, 55, 9, 7, 17};
    list_add(list, (void*) &add[0]);
    list_add(list, (void*) &add[1]);
    list_add(list, (void*) &add[2]);
    list_add(list, (void*) &add[3]);
    list_add(list, (void*) &add[4]);
    int size = list_size(list);
    int j = 0 ;
    while( j++ < 2)
    {
        for ( int i = 0 ; i < size; i++)
        {
            int* element = (int*) list_get(list, i);
            printf("Found %d\n", *element);
        }
        //I edited this line, now the second parameter is comparator
        list_sort(list, comparator); 
    }
    list_destroy(list);
}

ma​​in() 函数打印

找到 4
找到 55
找到 9
找到 7
找到 17
找到 17
找到 7
找到 9
找到 55
找到 4

编辑:

我创建了函数comparator,它实际上允许我运行代码

打印我之前显示的结果后,它会打印相同的列表,但向后打印。 感谢所有友善并帮助我解决此问题的人,我仍然不知道如何打印排序列表。抱歉,如果我的问题无用和/或违反了某些准则,如果我知道是这样,我不会这样问。

【问题讨论】:

  • 将指针传递给比较函数进行排序
  • bool cmp(void *a, void *b) { int *intA = a; int *intB = b; return *intA &lt; *intB; } 那你就可以ist_sort(list, cmp);
  • 需要定义一个函数bool comparator(void * a, void * b) { ... }并调用list_sort(list, comparator);
  • 它是指向bool func(void *, void *)类型函数的指针。
  • @JerryJeremiah 我做了...检查 while 语句...它只是向后打印它,如果函数比较器返回 (int*) a &lt; (int*) b 然后它像第一次一样打印它。

标签: c parameter-passing


【解决方案1】:

查看您上次编辑的代码,该函数完全错误。 (int*) a &gt; (int*) b 比较指针地址,而不是值。如果你打算返回true,如果a大于b,那么应该是:

bool is_greater (void * a, void * b) { 
    return *(int*) a > *(int*) b;
} 

更易读的写成:

bool is_greater (void* a, void* b) 
{ 
  const int* ia = a;
  const int* ib = b;    
  return *ia > *ib;
} 

该API使用的函数指针类型有一些代码味道,参数应该声明为const void*,这样代码也可以用于只读数据,但我想你不能改变那部分.

【讨论】:

    【解决方案2】:

    C++ 中,我们将有一个谓词 - 一个运算符,如果 lhs 则返回 true

    所以您的 C 函数看起来就像是遵循该模式。

    bool myLessInt(void * lhs, void * rhs)
    {
         // assume input parameters lhs and rhs are pointers into the data.
         int intLhs = *((int*)lhs);
         int intRhs = *((int*)rhs);
         if( intLhs < intRhs ) return true;  // lhs was less than rhs
         return false; // rhs == or is less than lhs
    }
    

    我会寻找类似上述的功能来解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      相关资源
      最近更新 更多