微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C 函数指针 - 未分配但仍然有效是否有默认行为?

如何解决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。

这是调用“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 举报,一经查实,本站将立刻删除。