Как привести указатель void к структуре в C?

В проекте, для которого я пишу код, у меня есть указатель void, «реализация», который является членом структуры «Hash_map» и указывает на структуру «Array_hash_map». Концепции этого проекта не очень реалистичны, но меня терпят. Спецификации проекта требуют, чтобы я преобразовал указатель void "implementation" в "Array_hash_map", прежде чем я смогу использовать его в каких-либо функциях.

Мой вопрос, в частности, заключается в том, что мне делать в функциях, чтобы привести указатели void к желаемой структуре? Есть ли один оператор в верхней части каждой функции, который их приводит, или мне нужно выполнять приведение каждый раз, когда я использую «реализацию»?

Вот определения типов структур Hash_map и Array_hash_map, а также пара функций, использующих их.

typedef struct {
  Key_compare_fn key_compare_fn;
  Key_delete_fn key_delete_fn;
  Data_compare_fn data_compare_fn;
  Data_delete_fn data_delete_fn;
  void *implementation;
} Hash_map;

typedef struct Array_hash_map{
  struct Unit *array;
  int size;
  int capacity;
} Array_hash_map;

typedef struct Unit{
  Key key;
  Data data;
} Unit;

функции:

/* Sets the value parameter to the value associated with the
   key parameter in the Hash_map. */
int get(Hash_map *map, Key key, Data *value){
  int i;
  if (map == NULL || value == NULL)
    return 0;
  for (i = 0; i < map->implementation->size; i++){
    if (map->key_compare_fn(map->implementation->array[i].key, key) == 0){
      *value = map->implementation->array[i].data;
      return 1;
    }
  }
  return 0;
}

/* Returns the number of values that can be stored in the Hash_map, since it is
   represented by an array. */
int current_capacity(Hash_map map){
  return map.implementation->capacity;
}

person Rowhawn    schedule 03.05.2010    source источник
comment
вроде, это небольшая часть большого проекта, над которым я работаю   -  person Rowhawn    schedule 04.05.2010


Ответы (1)


Вы можете преобразовать его каждый раз, когда используете его, или вы можете преобразовать его один раз и сохранить значение во временную переменную. Последний обычно самый чистый метод.

Например, вы можете использовать что-то вроде:

void my_function (Hash_Map* hmap) {
    Array_hash_map* pMap;

    pMap = hmap->implementation;

    // Now, you are free to use the pointer like it was an Array_hash_map
    pMap->size = 3; // etc, etc
}
person bta    schedule 04.05.2010
comment
Я понимаю, что вы говорите, но есть один спорный момент. Указатель void на самом деле является полем Hash_map, а также указывает на Array_hash_map. Могу я по-прежнему использовать способ map- ›implementation = (Array_hash_map *) map-› implementation; где map - это Hash_map, переданный в функцию, а реализация - это указатель void - person Rowhawn; 04.05.2010
comment
map->implementation = (Array_hash_map *) map->implementation был бы запретным. Тип, связанный с символом в данной области видимости, фиксируется в C - если map->implementation имеет тип void *, он всегда должен быть таким. - person caf; 04.05.2010
comment
Я понял, как много. Думаю, я просто сделаю Array_hash_map и установлю его на указатель void, как было предложено. Спасибо за помощь! - person Rowhawn; 04.05.2010