创建结构的实例

时间:2017-04-03 17:57:42

标签: c

我有这个结构

struct FluxCapacitor{
    unsigned char* c_string;
    unsigned int value;
};

现在我需要创建一个这个结构的实例。我搜索了这个问题,发现我必须使用这样的东西

typedef struct FluxCapacitor{
    unsigned char* c_string
    unsigned int value;
};  

但我真的不明白malloc()的下一步。有人可以向我解释一下吗?

2 个答案:

答案 0 :(得分:1)

您不需要malloc()来创建struct的实例。我建议你避免使用typedef结构来减少击键次数。额外的击键只会保存在声明和函数原型中(也可能是你需要投射的东西),因为你不需要在其他地方使用struct关键字;优点是,当您看到struct FluxCapacitor时,您确切知道它是什么。如果您仅看到FluxCapacitor,则不知道它是typedefstructunion,整数类型还是什么。

请注意,发布的代码在声明结尾处缺少分号。此外,还不清楚为什么你有unsigned char* c_string;。这可能不允许分配给字符串文字。我在下面的代码中对此进行了更改。您可以像这样创建一个struct

struct FluxCapacitor
{
    char *c_string;
    unsigned int value;
};

...

struct FluxCapacitor fcap_1;

然后,您可以将值分配给fcap_1

的字段
fcap_1.c_string = "McFly";
fcap_1.value = 42;

请注意,您还可以在声明时使用指定的初始值设定项:

struct FluxCapacitor fcap_2 = { .c_string = "Biff",
                                .value = 1985
};

如果您需要一个FluxCapacitor结构数组,只需声明一个:

struct FluxCapacitor fcaps[2];

您可以在循环中分配每个数组成员的字段:

struct FluxCapacitor fcaps[2];

char *somestrings[] = { "McFly", "Biff" };
unsigned somevalues[] = { 42, 1985 };

for (size_t i = 0; i < 2; i++) {
    fcaps[i].c_string = somestrings[i];
    fcaps[i].value = somevalues[i];
}

或者,您也可以在此处使用指定的初始值设定项:

struct FluxCapacitor fcaps[2] = { { .c_string = "McFly", .value = 42 },
                                  { .c_string = "Biff", .value = 1985}
};

使用malloc()

由于OP似乎决定使用malloc(),因此最好先回想一下,malloc()分配的内存必须在以后用free()解除分配。另请注意,malloc()无法分配内存,返回空指针。因此,在尝试取消引用此指针之前,必须检查对malloc()的调用结果。除非OP有充分理由进行人工分配,否则应避免使用上述方法的额外复杂性。

在下面的代码中,函数create_flux_cap()采用字符串和unsigned int作为参数,并返回指向新分配的FluxCapacitor结构的指针,并将参数分配给相应的字段。请注意,由于通过指针访问FluxCapacitor结构,因此使用箭头运算符而不是点运算符。

在函数内部,在尝试赋值之前检查调用malloc()的返回值。如果分配失败,则不进行分配,并将空指针返回给调用函数。请注意,在调用malloc()时,结果不会被强制转换,因为在C中不需要这样做,并且它会不必要地混淆代码。还要注意使用标识符而不是sizeof运算符的显式类型。如果类型在将来发生变化,这样就不容易出错,更容易维护,并且代码更清晰。也就是说,而不是:

new_fcap = (struct FluxCapacitor *)malloc(sizeof (struct FluxCapacitor));

使用它:

new_fcap = malloc(sizeof *new_fcap);

main()中,检查调用create_flux_cap()的返回值。如果分配失败,程序将退出并显示错误消息。

stdlib.hmalloc()的函数原型以及宏exit()已包含EXIT_FAILURE头文件。

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

struct FluxCapacitor
{
    char* c_string;
    unsigned value;
};

struct FluxCapacitor * create_flux_cap(char *, unsigned);

int main(void)
{
    struct FluxCapacitor *fcap_1 = create_flux_cap("McFly", 42);
    struct FluxCapacitor *fcap_2 = create_flux_cap("Biff", 1985);

    /* Check for allocation errors */
    if (fcap_1 == NULL || fcap_2 == NULL) {
        fprintf(stderr, "Unable to create FluxCapacitor\n");
        exit(EXIT_FAILURE);
    }

    /* Display contents of structures */
    printf("%s, %u\n", fcap_1->c_string, fcap_1->value);
    printf("%s, %u\n", fcap_2->c_string, fcap_2->value);

    /* Free allocated memory */
    free(fcap_1);
    free(fcap_2);

    return 0;
}

struct FluxCapacitor * create_flux_cap(char *str, unsigned val)
{
    struct FluxCapacitor *new_fcap;

    new_fcap = malloc(sizeof *new_fcap);

    if (new_fcap != NULL) {
        new_fcap->c_string = str;
        new_fcap->value = val;
    }

    return new_fcap;
}

答案 1 :(得分:-2)

你需要malloc来动态分配内存。在你的情况下,编译器都知道类型charint,这意味着编译器可以知道确切的内存需求在编译时。

例如您可以在struct函数

中创建main对象
 #include<stdio.h>
 #include<stdlib.h>
 struct FluxCapacitor{
    unsigned char* c_string;
    unsigned int value;
 };

 int main() {
     FluxCapacitor x;
     x.c_string = "This is x capacitor"
     x.value = 10
 }

x是值类型。您可以制作副本并传递此值。另外,请注意我们使用.表示法来访问其成员变量。

但这并不是一直发生的。我们不知道未来的FluxCapacitor要求,因此上面的程序需要更多的内存,因为它在运行时使用malloc我们可以要求编译器提供我们请求的内存。这是一个使用malloc的好地方,malloc的作用是,它返回一个指向所请求大小的内存的指针。它是动态内存分配。

以下是一个简单示例:假设您需要FluxCapacitor的结构声明,但不知道您需要多少,请使用malloc

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

typedef struct FluxCapacitor {
   unsigned char* c_string;
   int value;;
} flux;
// typedef is used to have the alias for the struct FluxCapacitor as flux

int main() {
    flux *a = malloc(sizeof(flux)); // piece of memory requested
    a -> c_string = "Hello World";  // Pointer notation
    a -> value = 5;

    free(a);                       // you need to handle freeing of memory
    return 0;
}