如何解决C 函数指针 - 未分配但仍然有效是否有默认行为?
我从一位高素质的讲师给我的程序中获得了此代码。注意下面的函数指针 cmpfn。它用作比较运算符。我做了一些关于函数指针的阅读,它们是有道理的。但是,在此代码库中,我没有看到它分配给实际定义的函数,就像我在在线阅读的教程中看到的那样。它从未在任何地方定义和分配,但它似乎可以工作。是否有一些默认行为,或者您如何在不分配它的情况下使其工作,如 cmpfn = &function_defined_elsewhere;
?还有为什么他会选择使用这个函数指针而不是直接的比较运算符?
/**
* Find an element in the list
*
* cmpfn should return 0 if the comparison to this node's data is equal.
*/
void *llist_find(struct llist *llist,void *data,int (*cmpfn)(void *,void *))
{
struct llist_node *n = llist->head;
if (n == NULL) {
return NULL;
}
while (n != NULL) {
if (cmpfn(data,n->data) == 0) {
break;
}
n = n->next;
}
if (n == NULL) {
return NULL;
}
return n->data;
}
编辑(响应反馈):解决了!以下内容适用于一般公众的教育/好奇心,但现在对我来说很有意义。感谢您的放纵。
我现在明白了,我需要找到调用此函数的位置。以上是在一个名为 llist.h 的文件中,指向函数 (p2f) 的指针在名为 hashtable.c 的文件中被调用 - 实际上两次。他实际上经常使用 p2f。
/**
* Get from the hash table with a binary data key
*/
void *hashtable_get_bin(struct hashtable *ht,void *key,int key_size)
{
int index = ht->hashf(key,key_size,ht->size);
struct llist *llist = ht->bucket[index];
struct htent cmpent;
cmpent.key = key;
cmpent.key_size = key_size;
struct htent *n = llist_find(llist,&cmpent,htcmp); // HERE
if (n == NULL) { return NULL; }
return n->data;
}
所以它正在通过 htcmp。以前我认为您必须将 p2f 分配给带有“=”的函数,但您也可以通过传入调用函数来实现。我今天才知道这些!
这是 htcmp 的定义:
/**
* Comparison function for hashtable entries
*/
int htcmp(void *a,void *b)
{
struct htent *entA = a,*entB = b;
int size_diff = entB->key_size - entA->key_size;
if (size_diff) {
return size_diff;
}
return memcmp(entA->key,entB->key,entA->key_size);
}
所以它清楚地返回一个int,取决于两个htent(哈希表条目)之间的差异,注意大小差异或调用强大的memcmp函数。
这是一个挑战。基础是有道理的,但他的代码很忙。我必须在睡梦中巩固它。有如此多的结构和指向函数的指针以及许多其他交互作用,但这是一次很棒的学习体验。
解决方法
您在此参数中设置指针。所以,当你调用这个函数时,我会自动设置这些指针。所以,我认为你应该看看这个函数的调用。然后你会得到你的问题的解决方案
void *llist_find(struct llist *llist,void *data,int (*cmpfn)(void *,void *))
,
当您调用函数 llist_find 时,您应该将引用传递给该函数,该函数必须具有与 lllist_find 预期相同的原型。
为了回答您的问题,使用指向函数的指针非常有帮助,尤其是当您使用可以对结构的一个或多个成员进行比较(这种情况下)的结构时。此外,由于该函数使用空指针,因此您可以使用相同的 llist_find 来处理不同类型结构的列表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。