我有一个作业,用户将在运行时指定他们想要创建的结构类型。
例如,假设用户输入:
name:char [50],address:char [50] and age:int
然后我的程序必须创建一个包含这3种变量的结构。请注意,用户可以为结构指定任意数量的变量,只将它们限制为char和int。
我的代码应该如何创建上面指定的结构?
这仅适用于c编程语言!
答案 0 :(得分:2)
变量有3个字段: 1)类型,2)名称,3)地址。 你shuold创建一个包含这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
。
name:char [50],address:char [50]和age: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
}
当你完成时不要忘记释放mallocs:
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);
您还需要一种方法来填充结构并打印它,等等......
答案 1 :(得分:1)
我一直在想这个,因为我正在考虑为一种语言编写FFI实现。 (虽然我怀疑,根据你接受的答案,你的用例有些不同)。
正如所指出的,结构只能在编译时生成,但这主要也是C语言的一个特性,可以启用类型检查,从而可以强制执行类型安全。
在运行时,您仍然可以将内存中的区域作为原始字节进行操作。您只需要根据要声明的数据类型的各个组件知道长度和偏移量,并相应地管理它们。
我从查看Ruby FFI库的实现方式中选择了这一点。以下是他们的文档:
当你调用Struct.new时,它会分配一个“内部字节”值 记忆吧。然后你做一个集合,比如struct [:member] = 3, 然后设置该结构中的位。反过来也是 真正; x = struct [:member]从原始内存中读取(和 每次访问时都转换为ruby对象)。记忆是 首次分配时“归零”,除非你自己传递 指针或指定它不清除内存(附加说明)。如果你 传递它指针它基本上使用它作为它的基础而不是 分配任何东西。
答案 2 :(得分:0)
“仅将它们限制为char和int”
因此,您可以创建通用数据类型(struct),保存带有name和char *的节点列表,以及带有name和int的节点列表。 在每个新输入上,您只需使用所需数量的char *和int节点填充列表。
要访问此类数据结构的字段,您需要遍历列表。 如果需要效率,可以将列表替换为映射(关联数组)。您需要在C上自己实现它。