如何将比较器传递给 C 函数?
How to pass a comparator to a C function?
什么是 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);
}
The main() function prints
Found 4
Found 55
Found 9
Found 7
Found 17
Found 17
Found 7
Found 9
Found 55
Found 4
编辑:
我创建了函数 comparator
,它实际上允许我 运行 代码
打印我之前显示的结果后,它打印了相同的列表,但向后打印。
感谢所有友善并帮助我解决此问题的人,我仍然不知道如何打印排序列表。对不起,如果我的问题没用 and/or 违反了一些准则,如果我知道我不会这样问。
在 C++
中我们将有一个谓词 - 一个运算符,如果 lhs < rhs
returns 为真
因此您的 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
}
我会寻找类似上述的功能来解决您的问题。
查看您上次编辑的代码,函数明显错误。 (int*) a > (int*) b
比较指针地址,而不是值。如果你打算returntrue
如果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*
这样代码也可以用于 read-only 数据,但我想你不能改变那部分。
什么是 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);
}
The main() function prints
Found 4
Found 55
Found 9
Found 7
Found 17
Found 17
Found 7
Found 9
Found 55
Found 4
编辑:
我创建了函数 comparator
,它实际上允许我 运行 代码
打印我之前显示的结果后,它打印了相同的列表,但向后打印。 感谢所有友善并帮助我解决此问题的人,我仍然不知道如何打印排序列表。对不起,如果我的问题没用 and/or 违反了一些准则,如果我知道我不会这样问。
在 C++
中我们将有一个谓词 - 一个运算符,如果 lhs < rhs
因此您的 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
}
我会寻找类似上述的功能来解决您的问题。
查看您上次编辑的代码,函数明显错误。 (int*) a > (int*) b
比较指针地址,而不是值。如果你打算returntrue
如果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*
这样代码也可以用于 read-only 数据,但我想你不能改变那部分。