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