在C中的数组中存储任意对象

Storing arbitrary objects in array in 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);
}

这可能吗?

是的。您可以创建一个 void 双指针 void** 并使用 malloc 为它分配 space 个(比如 10000)个 void 指针。它可以被索引并且有效地充当 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;
}

如果要存储很多类型,需要保存每个变量的大小或者类型。您应该使用 structunion。例如:

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