【问题标题】:Creating a certain struct at run time in c在c中运行时创建某个结构
【发布时间】:2014-02-28 01:12:27
【问题描述】:

我有一个分配,用户将在运行时指定他们想要创建的结构类型。

例如,假设用户输入:

姓名:char[50],地址:char[50],年龄:int

然后我的程序将不得不创建一个包含这 3 种类型变量的结构。请注意,用户可以为结构指定任意数量的变量,仅将它们限制为 char 和 int。

我的代码应该如何创建如上所述的结构?

这仅适用于 c 编程语言!

【问题讨论】:

  • C 是一种静态类型语言;你的程序需要实现一个解释器(最少),或者一个完整的编译器。
  • @ElliottFrisch 实际上,它没有强类型,而是静态类型。这些是不同的东西。根据您的评论,同意:我认为他不能以简单的方式做到这一点。
  • 你的意思可能不是真的struct。但是,您可以创建一个 dictionaryassociative container,让您可以将属性与字段名称相关联。用户在运行时指定的内容有时称为 schema

标签: c int runtime variable-assignment


【解决方案1】:

一个变量有 3 个字段: 1) 类型,2) 姓名,3) 地址。 你应该创建一个包含这 3 个结构的数组,这个结构的数组就是你想要的

您的结构可能如下所示:

typedef enum _Type{T_INT,T_STRING}Type;
typedef struct _var{
  Type type;
  char* name;
  union {int n; char* str;} data;
}var;

typedef struct _Struct{
  int count;
  var* array;
} Struct;

当你得到输入时,你需要根据它构建Struct。 姓名:char[50],地址:char[50],年龄:int

Struct *s = malloc(sizeof(Struct));
s->count = 3;//count of fields in the input
s->array = malloc(s->count*sizeof(var));
//you really should do it in a loop, after parsed the input...  
for(i=0;i<s->count;i++){
  s->array[i].name = strdup(parsedname);//"name", "address", "age"
  s->array[i].type = strcmp(parsedtype,"int")?T_STRING: T_INT;
  //for string you need to alloc memory for string...
  if(s->array[i].type == T_STRING)
    s->array[i].data.str=malloc(50 /*the size you've got*/);
  //not need to alloc memory for the int
}

完成后不要忘记释放 malloc:

for(i=0;i<s->count;i++){
 free(s-array[i].name);
 if(s->array[i].type == T_STRING)
   free(s->array[1].data.str);
}
free(s->array);
free(s);

您还需要一个方法来填充结构并打印它,等等...

【讨论】:

    【解决方案2】:

    我自己也一直在想这个问题,因为我正在考虑为一种语言编写 FFI 实现。 (尽管根据您接受的答案,我怀疑您的用例有所不同)。

    正如所指出的,结构只能在编译时生成,但这主要也是 C 语言的一个特性,可以启用类型检查,从而可以强制执行类型安全。

    在运行时,您仍然可以将内存中的区域作为原始字节进行操作。您只需要根据要声明的数据类型的各个组件了解长度和偏移量,并相应地管理它们。

    我是通过查看 Ruby FFI 库的实现方式来了解这一点的。以下来自他们的文档:

    当你调用 Struct.new 时,它会分配一个“内部字节” 那时的记忆。然后当你做一个集合时,比如 struct[:member] = 3, 该结构中的位随后被设置。倒数也是 真的; x = struct[:member] 从原始内存中读取(并且 翻译成一个红宝石对象),每次你访问它。记忆是 首次分配时“清零”,除非您传入自己的 指针或指定它以不清除内存(附加说明)。如果你 传递一个指针它基本上使用它作为它的基础而不是 分配任何东西。

    https://github.com/ffi/ffi/wiki/Structs#when-allocated

    【讨论】:

      【解决方案3】:

      "仅限制为 char 和 int"

      因此,您可以创建通用数据类型 (struct),其中包含具有名称和 char* 的节点列表,以及具有名称和 int 的节点列表。 在每个新输入中,您只需使用所需数量的 char* 和 int 节点填充列表。

      不过,要访问此类数据结构的字段,您需要遍历列表。 如果需要效率,可以将list替换为map(关联数组)。您需要像在 C 上一样自己实现它。

      【讨论】:

        猜你喜欢
        • 2021-08-18
        • 2011-11-06
        • 1970-01-01
        • 2012-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-02
        相关资源
        最近更新 更多