首页 > 解决方案 > 在 C 中创建和返回结构

问题描述

我有一个关于为结构创建和分配空间以及什么是“更好”的方法的问题。

假设我们有一堆参数,我们想基于它们创建一个结构。不直接存储所有参数,而是以某种方式处理它们并存储值。

例子:

typedef struct {
  int op;
  int res;
} Result;


int operation = 0; // 0 = addition, 1 = multiplication
int a = 2, int b = 3;
Result r;
r.op = operation;
if (operation == 0) {
  r.res = a+b;
else if(operation == 1) {
  r.res = a*b;
else {
 ...etc...
}

这些操作可能比这更复杂,并且可能有更多参数来定义最终结构。所以我想创建一个函数

create_structure(arg1, arg2, arg3, ..., argn) {
  switch(arg1) {
    case 0: struct_function0(arg1, arg2, arg3, ..., argn); break;
    case 1: struct_function1(arg1, arg2, arg3, ..., argn); break;
    ...
    case m: struct_functionm(arg1, arg2, arg3, ..., argn); break;
  }
}

所有这些函数都可以具有与“create_structure”类似的结构,并形成“函数创建树”,我们总是根据参数选择一个分支,直到我们到达某个最终会创建我们的结构的函数。我们还希望树的“根”返回一个指向存储该结构的内存位置的指针。

问题是如何从函数创建树的“叶子”返回创建的结构。

第一个选项是始终从内部函数返回结构,然后在树的根部为该结构分配内存并 memcpy 所有内容:

MyStruct* create_structure(arg1, arg2, arg3, ..., argn) {
  MyStruct s;
  switch(arg1) {
    case 0: s = struct_function0(arg1, arg2, arg3, ..., argn); break;
    case 1: s = struct_function1(arg1, arg2, arg3, ..., argn); break;
    ...
    case m: s = struct_functionm(arg1, arg2, arg3, ..., argn); break;
  }

  MyStruct* p_s = malloc(sizeof(MyStruct));
  memcpy(p_s, &s, sizeof(MyStruct));
  return p_s
}

另一种可能性是在根中拥有指向结构的指针,对其进行分配,然后将其作为参数发送到树的所有“分支”。像这样

MyStruct* create_structure(arg1, arg2, arg3, ..., argn) {
  MyStruct* p_s = malloc(sizeof(MyStruct));
  switch(arg1) {
    case 0: struct_function0(p_s, arg1, arg2, arg3, ..., argn); break;
    case 1: struct_function1(p_s, arg1, arg2, arg3, ..., argn); break;
    ...
    case m: struct_functionm(p_s, arg1, arg2, arg3, ..., argn); break;
  }

  return p_s;
}

在第二个变体中,我们将通过树中的所有函数传递参数 p_s 直到我们到达叶子。
还有一个可能的第三种选择,malloc 可以在树的叶子中。

这些可能性中的哪一个更受欢迎?还有其他选择吗?

标签: cc99

解决方案


我会让调用者决定如何分配 MyStruct 以便调用者知道是否或如何取消分配。

void create_structure(MyStruct *s, arg1, arg2, arg3, ..., argn) {
  switch(arg1) {
    case 0: struct_function0(s, arg1, arg2, arg3, ..., argn); break;
    case 1: struct_function1(s, arg1, arg2, arg3, ..., argn); break;
  }
}

MyStruct s;
create_structure(&s, 1,2,3);

或者

MyStruct *s2 = malloc(sizeof *s2);
create_structure(s2, 1,2,3);

free(s2);

推荐阅读