Можно ли наследовать от структуры, не имея другой инициализированной структуры в C - PullRequest
1 голос
/ 25 февраля 2020

Я - новый студент структур данных и пытаюсь ознакомиться со c структурами. Я знаю наследование из моего прошлого python опыта, поэтому я хотел псевдо попробовать его в c. Мой код выглядит так:

typedef struct{
    char name[20];
    int age;
    int weight;
    int selling_price;
} Animal;

typedef struct{
    Animal *animal;
    int can_speak;
}super_animal;

int main() {
    Animal monkey;
    strcpy(monkey.name,"Mustafa");
    monkey.age=19;
    monkey.weight=80;

    super_animal human;
    human.animal=&monkey;
    human.can_speak=1;
    printf("%s, can speak bool:%d\n",human.animal->name,human.can_speak);
    return 0;
}

Я хочу вырезать этот средний шаг обезьяны из кода. Можно ли использовать такой указатель структуры без назначения?

1 Ответ

5 голосов
/ 25 февраля 2020

Пока animal имеет тип Animal *, он должен указывать на действительную память перед использованием. Эта память не должна иметь имя или ссылаться на другой указатель с именем. То есть вы можете удалить отдельную переменную monkey, непосредственно выделив память для human:

super_animal human = { .animal = malloc(sizeof *human.animal), .can_speak = 1 };
if (human.animal == NULL)
    HandleError();
strcpy(human.animal->name, "Mustafa");
human.animal->age = 19;
human.animal->weight = 80;

Если вместо этого вы измените тип элемента animal на Animal вместо Animal *:

typedef struct{
    Animal animal;
    int can_speak;
}super_animal;

, таким образом, встраивая структуру Animal непосредственно в структуру super_animal, тогда вам не нужно предоставлять отдельную память:

super_animal human = { .animal.name = "Mustafa", .animal.age = 19, .animal.weight = 80, .can_speak = 1 };
printf("%s, can speak bool:%d\n",human.animal.name,human.can_speak);

Обратите внимание, что это изменяется .animal.name чтобы указывать на строковый литерал напрямую, а не делать его копию. Это не обязательно для этого примера. Существует множество способов решить, как обрабатывать имя, как инициализировать структуру и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...