C - 从void *函数中的结构更改变量值

时间:2017-04-17 22:07:48

标签: c

我在C学校做了一个练习,我无法改变主要功能的内容以及其他两个功能的类型和参数。我已经搜索了谷歌,但没有找到我的理解我的问题的答案。

目标只是用printf显示结构的内容,但由于不知道如何将结构返回到main函数,我有一个错误。

这是代码:

 void   *create_mage(t_character *perso)
 {
   if ((perso = malloc(sizeof(t_character))) == NULL)
     exit(84);
   perso->niveau = 1;
   perso->pdv = 100;
   perso->mana = 200;
   perso->attaque = 40;
   perso->defense = 3;
   perso->crit_chance = 10;
   perso->vitesse = 4;
   return (perso);
 }

void    *create_warrior(t_character *perso)
{
   if ((perso = malloc(sizeof(t_character))) == NULL)
     exit(84);
   perso->niveau = 1;
   perso->pdv = 200;
   perso->mana = 50;
   perso->attaque = 10;
   perso->defense = 8;
   perso->crit_chance = 10;
   perso->vitesse = 3;
   return (perso);
 }

int            main()
{
   t_character p_ava;
   t_character p_thi;

   p_ava = create_mage(&p_ava);
   p_thi = create_warrior(&p_thi);
   printf("def %d - atk %d - vit %d - crit %d\n", p_ava.defense, 
   p_thi.attaque, p_ava.vitesse, p_thi.crit_chance);
   return (0);
}

这是我编译项目时遇到的错误:

gcc *.c -Wall -Wextra
create_class.c: In function ‘main’:
create_class.c:48:9: error: incompatible types when assigning to type ‘t_character {aka struct s_character}’ from type ‘void *’
   p_ava = create_mage(&p_ava);
         ^
create_class.c:49:9: error: incompatible types when assigning to type ‘t_character {aka struct s_character}’ from type ‘void *’
   p_thi = create_warrior(&p_thi);
         ^

我没有关于结构如何工作的好概念,也没有找到任何关于从void *函数返回结构的内容,所以如果你有一个答案或链接,我可以找到一个问题,那将非常受欢迎。提前谢谢!

1 个答案:

答案 0 :(得分:0)

如果您无法更改main,则无法编译代码 - 期间(请参阅J. Leffler的评论,上文)。但是,如果“更改”意味着您“无法添加到”,那么您就可以了。为什么呢?

您真正需要做的就是在struct之外声明typedef(或者更好地简单地将t_character所需结构声明为main),然后在main 删除 p_ava =p_thi =以及删除每个功能中对malloc的调用细

为什么呢?声明结构时:

t_character p_ava;
t_character p_thi;

您为每个变量创建了type t_character的存储空间。编译器只需要知道该类型是什么。因此,您定义t_character结构(或typdef),您的编译器将为变量提供足够的存储空间,例如

typedef struct {
    int niveau, pdv, mana, attaque, defense, crit_chance, vitesse;
} t_character;

当您将变量传递给函数(例如create_mage(&p_ava);)时,您将地址 p_ava传递给您的函数。已为该地址的t_character 创建了足够的存储空间。所以你需要在函数中做的就是验证你传递给函数的变量的有效地址,然后只填充结构的成员值。

将这些碎片放在一起,你可以(不是'改变',而是'删除')并执行以下操作:

#include <stdio.h>
#include <stdlib.h> /* for exit() */

typedef struct {
    int niveau, pdv, mana, attaque, defense, crit_chance, vitesse;
} t_character;

void *create_mage (t_character *perso)
{
    if (!perso) {
        fprintf (stderr, "create_mage() error: invalid parameter.\n"); 
        exit (84);
    }
    perso->niveau = 1;
    perso->pdv = 100;
    perso->mana = 200;
    perso->attaque = 40;
    perso->defense = 3;
    perso->crit_chance = 10;
    perso->vitesse = 4;
    return (perso);
}

void *create_warrior (t_character * perso)
{
    if (!perso) {
        fprintf (stderr, "create_warrior() error: invalid parameter.\n"); 
        exit (84);
    }
    perso->niveau = 1;
    perso->pdv = 200;
    perso->mana = 50;
    perso->attaque = 10;
    perso->defense = 8;
    perso->crit_chance = 10;
    perso->vitesse = 3;
    return (perso);
}

int main (void)
{
    t_character p_ava;
    t_character p_thi;

    create_mage (&p_ava);
    create_warrior (&p_thi);

    printf ("def %d - atk %d - vit %d - crit %d\n", p_ava.defense,
            p_thi.attaque, p_ava.vitesse, p_thi.crit_chance);

    return 0;
}

注意:您可以摆脱fprint语句和有效指针的测试,因为'变更'是验证的习惯问题函数参数,但不是函数成功运行所必需的。

<强>编译

$ gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o bin/magewarrior magewarrior.c

示例使用/输出

$ ./bin/magewarrior
def 3 - atk 10 - vit 4 - crit 10

仔细看看,如果您有任何疑问,请告诉我。如果你无法通过删除离开,那么你几乎就没有桨了......

您的备选方案是按照评论中的说明制作p_avap_thi指针(将'.'运算符替换为您'->'中的printf箭头运算符),然后您可以在函数中使用malloc进行分配,但是会收到警告以传递p_avap_thi未初始化,除非在调用之前初始化指针NULL:< / p>

p_ava = create_mage (p_ava);

这需要对main进行更多更改,例如

int main (void)
{
    t_character *p_ava = NULL;
    t_character *p_thi = NULL;

    p_ava = create_mage (p_ava);
    p_thi = create_warrior (p_thi);

    printf ("def %d - atk %d - vit %d - crit %d\n", p_ava->defense,
            p_thi->attaque, p_ava->vitesse, p_thi->crit_chance);

    return 0;
}

你必须做一个或另一个。