Хранение произвольных объектов в массиве в C - PullRequest
0 голосов
/ 11 апреля 2020

Я новичок в C, но пытаюсь обернуть голову, пытаясь сохранить произвольные объекты в массиве. Структуры, целые числа, символы, функции и т. Д. c. По сути, что-то, возможно, с использованием пустых указателей вдоль строк (псевдокод):

void *array[] = malloc(10000);
struct MyStruct m = malloc(sizeof(m));
int x = 10;
char c[] = "Look Here";
array[0] = &m;
array[1] = &x;
array[2] = &c;

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

void *global_array[];

void
get_from_array(int index, void *ptr) {
  *ptr = global_array[index];
}

int
main() {
  global_array = malloc(10000);
  struct MyStruct m = malloc(sizeof(m));
  int x = 10;
  char c[] = "Look Here";
  global_array[0] = &m;
  global_array[1] = &x;
  global_array[2] = &c;
  struct MyStruct m2;
  get_from_array(0, &m2);
  assert(m == m2);
}

Возможно ли что-нибудь подобное?

Ответы [ 2 ]

3 голосов
/ 11 апреля 2020

Да. Вы можете создать двойной указатель void void** и выделить ему пространство (скажем, 10000) указателей void с помощью mallo c. Его можно проиндексировать, и он эффективно действует как массив типа void* типа

. Для кода, упомянутого в вашем вопросе, это будет что-то вроде

# include <stdio.h>
# include <stdlib.h>


void **array;

typedef struct MyStruct{
  int a;
  char b;
}MyStruct;

int main()
{
  array = malloc(sizeof(void*)*10000);
  struct MyStruct* m = (MyStruct*)malloc(sizeof(MyStruct));
  m->a=1;
  m->b='x';
  int x = 10;
  char c[] = "Look Here";
  array[0] = m;
  array[1] = &x;
  array[2] = &c;
  printf("%d %c\n%d\n%s\n",((MyStruct*)(array[0]))->a,((MyStruct*)(array[0]))->b,*(int*)(array[1]),(char*)(array[2]));
  return 0;
}
1 голос
/ 11 апреля 2020

Если вы хотите хранить много типов, вам нужно сохранить размер или тип каждой переменной. Вы должны использовать struct и union. Например:

typedef enum EltType { TYPE_STRING, TYPE_INT, TYPE_FLOAT } TYPE;
typedef struct Element {
  TYPE type;
  union {
    char  *str;
    int    i;
    float  f;
  };
}ELEMENT;

Тест:

#include <stdio.h>

typedef enum EltType { TYPE_STRING, TYPE_INT, TYPE_FLOAT } TYPE;
typedef struct Element {
  TYPE type;
  union {
    char  *str;
    int    i;
    float  f;
  };
}ELEMENT;

void print_value(ELEMENT elt) {
    switch (elt.type) {
        case TYPE_STRING:
           printf("%s\n", elt.str);
           break;
        case TYPE_INT:
           printf("%d\n", elt.i);
           break;
        case TYPE_FLOAT:
           printf("%f\n", elt.f);
           break;
    }
}
int main(int argc, char const *argv[])
{
    ELEMENT elt1, elt2, elt3; 
    elt1.type = TYPE_STRING;
    elt1.str = "string";

    elt2.type = TYPE_INT;
    elt2.i = 5;

    elt3.type = TYPE_FLOAT;
    elt3.f = 1.2;

    print_value(elt1);
    print_value(elt2);
    print_value(elt3);

    return 0;
}

...