传递给void*指针的结构体元素访问

3
我正在使用二叉搜索树数据结构对一系列类型为以下定义的结构体进行排序:

typedef struct {
    char c;
    int index;
} data_t;

typedef struct node node_t;

typedef node {
    void *data;
    node_t *left;
    node_t *right;
}

node_t是一个typedef,来自于我为此目的提供的库,假定使用void*指针以确保多态性。node将被传递到以下函数中:

static void *recursive_search_tree(node_t *root, void *key, int cmp(void*,void*))

在recursive_search_tree函数内部,我想修改代码,使用索引元素作为条件来查找最接近线性遍历字符数组索引的匹配项,这最终涉及将数据传递到*key,并在函数中访问key->index

问题

是否有可能访问key->index,其中key是指向data_t结构体的void*指针?还是只有当将data_t声明为key的类型时才可能实现?我已经尝试了后者,但即使将指针转换为int,编译器似乎也无法通过。


2
重新转换无返回值函数参数应该会有所帮助。 - DCoder
2个回答

4
当然可以,你需要将 key 转换为类型 *data_t。(前提是 key 确实是指向 *data_t 的指针!)
key                     /* argument of type void* */
(data_t*)key            /* cast as type data_t*   */
((data_t*)key)->index   /* dereferenced */

这里有一个简单的例子:
#include <stdlib.h>
#include <stdio.h>

typedef struct {
    char    c;
    int     index;
} data_t;

typedef struct node {
    void    *data;
    struct node *left;
    struct node *right;
} node_t;

static int cmp(void *lhs, void *rhs)
{
    return ((data_t *)lhs)->index - ((data_t *)rhs)->index;
}

int main(void)
{
    data_t d0;
    data_t d1;

    d0.c     = 'A';
    d0.index = 1;
    d1.c     = 'B';
    d1.index = 2;

    printf("d0 < d1? %s\n", (cmp((void *)&d0, (void *)&d1) < 0 ? "yes" : "no"));
    printf("d1 < d0? %s\n", (cmp((void *)&d1, (void *)&d0) < 0 ? "yes" : "no"));

    return EXIT_SUCCESS;
}

0
这是不安全类型,任何使用void的都是如此。使用void通常是因为中间件正在为他人方便而保留它不使用的内容。这是一个C函数,让您在树中持有任何想要的内容。它所做的就是返回您给它的任何指针。
在您的搜索函数中。
int cmp(void* dt1, void* dt2)
{
data_t*  data1 = (data_t*)dt1;
data_t*  data2 = (data_t*)dt2;
/* Do what you need with data1 and data2 here */
}

应该让你做任何你需要的事情。你遇到的问题是需要在函数内部转换你的值。cmp 的参数应该与你使用的库的 API 完全匹配,API 中的参数类型为 void*。


谢谢!我已经尝试过这个,因为我正在比较字符,但是我似乎得到了一些奇怪的错误信息,例如: treeops.h:1: error: redefinition of typedef ‘node_t’ treeops.h:1: error: previous declaration of ‘node_t’ was here 以及对于函数: treeops.h:15: error: conflicting types for ‘make_empty_tree’ treeops.h:15: error: previous declaration of ‘make_empty_tree’ was here - disgruntledperson
好的,我已经成功解决了错误。看起来这些错误是因为我在两个不同的C文件中两次包含了同一个头文件... - disgruntledperson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接