在c中取消引用Void指针

时间:2014-09-04 22:56:13

标签: c pointers null

我在尝试顺从C中的空指针时遇到了麻烦。

好吧,我制作一个链接列表,其中包含一个带有void * info的“Nodo”,这是因为info会改变类型。

typedef struct nodo
{
    void *info; //This'll change types, like different structs.
    char label; // S si es un switch, E si es un enemigo
    struct nodo *siguiente;
}tNodo;

typedef struct Lista {
    tNodo *head;
    tNodo *tail;
    tNodo *curr;
    unsigned int listSize;
    unsigned int pos;
}tLista;

这是我的struct tEnemigo,这将是信息可以采用的结构之一。

typedef struct
{
    char(*siguiente_movimiento)(void *,char **,int,int);
    char tipo;
    int maxmov;
    int pasos;
    char direccion;
    int y;
    int x;
}tEnemigo;

在这个函数中,我只是传递void * general来获取它的信息

char movEnemigos(tLista *listaEnemigos, char **map)
{
void *general;
general = &listaEnemigos->curr->info; //A struct 
siguiente_movimiento(general, map , x, y);
}

这是我的问题,我不能给出位于一般的“信息”,我读了一些关于投射虚空指针的东西,但我失败了。

char siguiente_movimiento(void *general, char **map, int x, int y)
{
tEnemigo *enemigo;
enemigo = *(tEnemigo *) general ;
}

我不知道怎么做,也许我对代码的所有“想法”都错了...希望你们能帮我一臂之力。

编辑:这是错误代码。

error: incompatible types when assigning to type ‘tEnemigo’ from type ‘struct tEnemigo      *’
      *(tEnemigo *) general = enemigo;

2 个答案:

答案 0 :(得分:1)

siguiente_movimiento函数中,enemigo是一个指针,但您正在尝试为其指定一个而不是指针的值(因为您使用{取消引用它) {1}})。你的功能应如下所示:

*

或者:

char siguiente_movimiento(void *general, char **map, int x, int y)
{
    tEnemigo enemigo;
    enemigo = *(tEnemigo *) general ;
}

您目前混合了两者。

答案 1 :(得分:0)

错误消息让游戏消失 - 您尚未声明类型struct tEnemigo

你有:

typedef struct
{
    ...
}tEnemigo;

您需要在使用类型时删除struct,或者您需要:

typedef struct tEnemigo
{
    ...
} tEnemigo;

这两种技术都有效。我可能无论如何都要添加标签,但我肯定会根据typedef名称(仅tEnemigo)编写代码,而不是struct tEnemigo

而且,作为旁注,你的目标应该是避免void *个论点。 struct tEnemigo标记的一个优点是您可以通过简单地说:

来定义不透明类型
struct tEnemigo;   // There is a type struct tEnemigo...

char siguiente_movimiento(struct tEnemigo *enemigo, char **map, int x, int y);

使用struct tEnemigo指针的代码不需要知道结构的内部结构;只有需要查看结构内部的代码才需要知道完整的类型定义。

避免void *参数的一个原因是任何指针类型都可以传递给期望void *的函数。例如,如果您有FILE *fp = fopen("something", "r);,则编译器无法在以下位置诊断错误:

char c = siguiente_movimiento(fp, map, 1, 3);

即使这显然是一个错误。使用函数的struct tEnemigo *声明,此错误将成为编译错误。

经验法则:如果void *参数仅映射到单个类型,则不应使用void *参数写入函数。 (也有例外:例如,如果你有一系列由函数指针调用的函数,你可能需要一个void *参数,这样一个调用就可以调用任何函数。内存分配函数是另一种特殊情况。 )