我在C中有一个通用链接列表,它知道如何将结构推送到列表中。
问题是我无法在这些链接列表中实现通用搜索:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
struct Node
{
void *data;
struct Node *next;
};
void push(struct Node** head_ref, void *new_data, size_t data_size)
{
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = malloc(data_size);
new_node->next = (*head_ref);
int i;
for (i=0; i<data_size; i++)
*(char *)(new_node->data + i) = *(char *)(new_data + i);
(*head_ref) = new_node;
}
struct A
{
int a1;
long a2;
};
struct B
{
long b1;
int b2;
};
void find_a1_in_a_list (int desire_a1 , struct Node *a_list)
{
struct A *a;
while(NULL != a_list)
{
a = (struct A*) a_list->data;
if(a->a1 == desire_a1)
printf("found!n");
a_list = a_list->next;
}
}
void find_b1_in_b_list (long desire_b1 , struct Node *b_list)
{
struct B *b;
while(NULL != b_list)
{
b = (struct B*) b_list->data;
if(b->b1 == desire_b1)
printf("found!n");
b_list = b_list->next;
}
}
void find_generic (void* desire_value,int off,struct Node *list)
{
while(NULL != list)
{
void* check_value_void = list->data + off;
int check_value_cast = *(int *) check_value_void; //How to know if cast to int or long ?????
if(check_value_cast == *(int *)desire_value) //How to know if cast to int or long ?????
printf("found generic!n");
list = list->next;
}
}
void main()
{
struct Node *a_list = NULL;
struct A a;
a.a1=1;
a.a2=2;
push(&a_list, &a, sizeof(struct A));
find_a1_in_a_list(1,a_list);
struct Node *b_list = NULL;
struct B b;
b.b1=1;
b.b2=2;
push(&b_list, &b, sizeof(struct B));
find_b1_in_b_list(1,b_list);
//tried to make it generic
int search = 3;
find_generic(&search,offsetof(struct A, a2),a_list);
}
正如你所知,我试图通过将偏移量传递到结构中的值来在函数find_generic
中进行通用搜索,该代码可以工作,但仅适用于int
但是,如果我想搜索int或long,我该如何传递给这个泛型函数,这样我就知道如何进行cast了?
有没有办法按大小铸造void*,这样我就可以通过sizeof(int)
或sizeof(long)
,并按这个值铸造?或者换一种方式?
直接传递compare函数而不是玩offsetof
/sizeof
会更灵活:
struct Node *find_generic (struct Node *list,
int (*fn_cmp)(void const *a, void const *b),
void const *data)
{
while (list) {
if (fn_cmp(list->data, data) == 0)
break;
list = list->next;
}
return list;
}
然后创建自定义比较函数
static int cmp_A(void const *a_, void const *b_)
{
struct A const *a = a_;
struct A const *b = b_;
if (a->a1 == b->a1 && a->a2 == b->a2)
return 0;
return 1;
}
并称之为
struct A key = {
.a1 = 23,
.a2 = 42,
};
find_generic(a_list, cmp_A, &key);