在C中初始化结构,最佳实践

在C中初始化结构,最佳实践,c,ansi,C,Ansi,在这段代码中初始化成员结构时,我遇到了一个编译时错误。 还有什么其他方法可以初始化下面的数组结构。 谢谢大家! #include <stdio.h> #include <stdlib.h> #define MAX_FUNC_MEMBERS 100 #define MAX_FUNC_DESC_STR 50 typedef struct member_struct { double degree; double coefficient; } member;

在这段代码中初始化成员结构时,我遇到了一个编译时错误。 还有什么其他方法可以初始化下面的数组结构。 谢谢大家!

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

#define MAX_FUNC_MEMBERS 100
#define MAX_FUNC_DESC_STR 50

typedef struct member_struct {
    double degree;
    double coefficient;
} member;

typedef struct function_struct{
    member members[MAX_FUNC_MEMBERS];
    char *description;
} *function;

function malloc_function() {
    return (function) malloc(sizeof(struct function_struct));
}

double compute_function(function f, double x) {
    return 0.0;
}

int main(void) {
    // f1 = x^2
    function f;
    f->members = {
        [0] = {2.0, 1.0},
        [1] = {1.0, 1.0}
    };
    f->description = "x squared";

    return 0;
}
#包括
#包括
#定义最大函数成员100
#定义最大函数描述长度50
类型定义结构成员\u结构{
双学位;
双系数;
}成员;
typedef结构函数{
成员成员[最大功能成员];
字符*描述;
}*功能;
函数malloc_函数(){
返回(函数)malloc(sizeof(struct function_struct));
}
双计算函数(函数f,双x){
返回0.0;
}
内部主(空){
//f1=x^2
函数f;
f->成员={
[0] = {2.0, 1.0},
[1] = {1.0, 1.0}
};
f->description=“x平方”;
返回0;
}

您有一个
字符*
,但尚未为它所指向的字符串分配内存

你可以这样做:

function f = malloc(sizeof(function));
const char *desc = "x squared";
f->description = malloc(strlen(desc) + 1);
strcpy(f->description, desc);
要验证它是否有效,请执行以下操作:

fprintf(stderr, "description: %s\n", f->description);

但是,在您的特定情况下,您的程序即使已编译,也会发生SEGFULT,因为您正在将数据分配给
*f
,而不进行分配

有几种可能的解决方案。最简单的方法可能是简单地在堆栈上分配
函数
结构,但这需要您修改它的
typedef
而不是指针,或者直接使用结构名称。对于这个示例,我将使用后面的:

struct function_struct fbuf = {
    .members = {
        [0] = {2.0, 1.0},
        [1] = {1.0, 1.0}
    },
    .description = "x squared",
};
function f = &fbuf;
另一种方法是手动逐个初始化成员:

f = malloc(sizeof(*f)):
f->members[0].degree = 2.0;
f->members[0].coefficient = 1.0;
f->members[0].degree = 1.0;
f->members[0].coefficient = 1.0;
f->description = "x squared";
第三种可能是使用复合文字:

f = &(struct function_struct) {
    .members = {
        [0] = {2.0, 1.0},
        [1] = {1.0, 1.0},
    },
    .description = "apa",
};
最后一个与第一个基本相同,只是
fbuf
是匿名的

如果希望在堆上而不是堆栈上分配结构的内存,还可以将第二个和第三个组合起来:

f = malloc(sizeof(*f)):
*f = (struct function_struct) {
    .members = {
        [0] = {2.0, 1.0},
        [1] = {1.0, 1.0},
    },
    .description = "apa",
};
至于你的“最佳实践”方面,我不认为这两个方面本质上比任何其他方面都好或坏,但它们在某些方面确实有所不同:

  • 第三个和第四个,使用复合文本,需要C的后一个版本,所以如果你想要兼容古老的C编译器,它们是个坏主意。然而,如今这应该是一个罕见的问题
  • 第一个和第三个在堆栈上分配数据,而第二个和第四个在堆上分配数据。这是不同的,而不是更好或更糟,所以选择哪个适合您的场景
  • 根据编译器的不同,第二个示例可能更快,因为它不涉及未使用的98个成员。然而,要想成为一个问题,您必须在一个非常紧密的循环中初始化大量的
    函数
    结构。:)
    
我怀疑
f->members
初始化。这方面的最佳实践是非常主观的。我个人永远不会对数组使用指定的初始值设定项,因为。。。这样做没有多大意义。如果您有一个数组,无论出于何种原因,需要将每个数组成员视为特例,那么您必须在每一行上添加注释。然而,这实际上不是他的问题,因为他没有执行strcpy
。简单地给它分配一个静态字符串文字应该没有任何问题。还有一件事我想知道,这种类型的初始化是否适用于ANSI C。这取决于哪个ANSI C。第三个和第四个示例不适用于ANSI C89,但这是古老的历史。他们中的任何人都不应该对ANSI C99或ANSI C11有任何问题。还有,我所做的f->members声明中的错误是什么。即使在为函数声明分配了空间之后,我仍然会遇到这个错误。问题是语法是无效的,非常简单。复合初始值设定项仅在变量定义位置有效,在任意赋值中无效。在后一种情况下,您需要使用复合文字,如我的第三个和第四个示例中所示。但是,数组不支持复合文字(这不完全正确,但在这种情况下就足够了),因此在您的情况下也不支持复合文字。再次感谢您!你的回答很有描述性