Элемент доступа структуры, переданный в указатель void*

Я работаю со структурой данных бинарного дерева поиска, чтобы отсортировать серию структур с определениями типов:

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 взят из библиотеки, предоставленной мне для этой цели, предположительно с указателем void * для обеспечения полиморфизма. node будет передано в функцию:

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

В функции recursive_search_tree я хочу иметь возможность изменять код, чтобы использовать элемент индекса в качестве условия для нахождения соответствия, наиболее близкого к индексу линейного прохода по массиву символов, что в конечном итоге приведет к передаче data_t в *key а также key->index доступ к функции.

Вопрос

Возможно ли получить доступ key->index где ключ является void* указывая на data_t структура, или это было бы возможно только если data_t был объявлен как тип для ключа? Я пытался сделать последнее, однако даже приведение указателя на int, похоже, не проходит компилятор.

2 ответа

Конечно, это возможно, вы бы бросили key как тип *data_t, (Пока это действительно то, что key указывает на!)

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;
}

Это небезопасный тип, как и любое использование 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 для библиотеки, которую вы используете, что говорит void* для параметров.

Другие вопросы по тегам