正确地在C中初始化递归结构类型

时间:2017-07-16 20:30:39

标签: c recursion struct

我是C编程新手,我有以下结构:

typedef struct _date {
    char d[10], t[5], s[3];
    struct _date *next;
} *date;

如何正确创建此实例?

我的解决方案:

date neuerTermin(char *d, char *t, char *s, date cal) {
    struct _date d = {*d, *t, *s, NULL};
    date d_ptr = malloc(sizeof *d);
    cal->next = d_ptr;

    return d;
}

但我收到错误:warning: initialization makes integer from pointer without a cast

2 个答案:

答案 0 :(得分:2)

虽然Akira对你有一个非常好的答案(我投了赞成票),但我会提醒你 typedeffing pointers 。为什么?随着项目的增长,当您开始隐藏typedef后面的间接级别时,混淆程度和错误可能性会增加。

如果需要typedeffed类型的指针,请声明一个实例,但要将typedef保留为类型,以便不屏蔽间接级别。

您可以在不隐藏间接级别的情况下执行相同的操作,如下所示:

#include <stdio.h>

typedef struct _date {
    char d[11], t[6], s[4]; // +1 for '\0'
    struct _date *next;
} date;


int main() {
    date a = { "15.07.2017", "16:00", "Foo", NULL };
    date *a_ptr = &a;

    printf("Description: %s\nDate: %s\nTime: %s\n", a_ptr->s, a_ptr->d, a_ptr->t);
    return 0;
}

示例使用/输出

PS> .\bin\structtypedef.exe
Description: Foo
Date: 15.07.2017
Time: 16:00

Typedeffing指针现在是错误的,它只会造成陷阱。请参阅:In C, is it good form to use typedef for a pointer?

答案 1 :(得分:1)

您可以按照以下方式执行此操作:

#include <stdio.h>

typedef struct _date {
    char d[11], t[6], s[4]; // +1 to size for null-terminator ('\0')
    struct _date *next;
} *date;


int main() {
    struct _date a = { "15.07.2017", "16:00", "Foo", NULL };
    date a_ptr = &a;

    printf("Description: %s\nDate: %s\nTime: %s\n", a_ptr->s, a_ptr->d, a_ptr->t);
    return 0;
}

上面示例中括号括起的逗号分隔列表是struct initializer

要回复您问题的修改,如果您希望动态分配struct _date个实例并在函数中初始化它们,请按以下方式使用malloc

date neuerTermin(const char* d, const char* t, const char* s) {
    date cal = (date)malloc(sizeof(struct _date));

    strncpy(cal->d, d, 10);
    strncpy(cal->t, t, 5);
    strncpy(cal->s, s, 3);
    cal->next = NULL;

    return cal;
}

在这种情况下,您必须填充cal成员指向的内存块。样品用法:

date root = neuerTermin("15.07.2017", "16:00", "Foo");
root->next = neuerTermin("27.07.2017", "10:00", "Bar");
root->next->next = neuerTermin("01.08.2017", "12:30", "Baz");

重要提示:如果您使用malloc分配内存,则必须在不再需要时使用free解除分配。