如何基于条件对无效指针进行类型转换?

时间:2015-05-13 15:59:18

标签: c pointers if-statement casting void

为了解释更多,我有两个结构 - '第一个'和第二个'有共同的变量' jack'并且' jill'。我想通过基于if-else条件的指针来打印插孔。 据我所知,在打印时我必须对void指针进行类型转换。但是指针指向struct a还是b是在运行时决定的。 这是一个基本的C代码。如何克服这个?

代码

#include <stdio.h>

int main(void)
{

typedef struct one
{
    int jack;
    float jill;
}a;
typedef struct two
{
    int jack;
    float jill;
    char something;
    int something1;
}b;
a first;
b second;

void *z;

if(1)
{
    a* z;
    z = &first;
    printf("First one");
}
else
{
    b* z;
    z = &second;
    printf("Second one");
}

printf("%d\n", z->jack);


    return 0;
}

错误

prog.c:36:17: warning: dereferencing 'void *' pointer printf("%d\n", z->jack); prog.c:36:17: error: request for member 'jack' in something not a structure or union

1 个答案:

答案 0 :(得分:2)

您收到编译器警告,因为编译器不理解z->jack,因为zvoid *(请注意,声明a* zb* z不是在ifelse块的范围之外有效。

要解决此问题,您可以使用以下列表中所示的函数printJack

#include <stdio.h>

typedef struct one
{
    int jack;
    float jill;
}a;

typedef struct two
{
    int jack;
    float jill;
    char something;
    int something1;
}b;


void printJack(void *pStruct, int type)
{
    switch (type)
    {
        case 1:
            printf("jack: %d\n", ((a *)pStruct)->jack);
            break;

        default:
            printf("jack: %d\n", ((b *)pStruct)->jack);
            break;
    }
}


/*
**    main
*/
int main(void)
{
    a first;
    b second;
    void *z;

    first.jack = 5;
    second.jack = 4892;

    printJack(&first, 1);
    printJack(&second, 0);

    z = &first;
    printJack(z, 1);

    return (0);
}

我经常编写这样的代码并且经历了很多麻烦。不是在实施时,因为您知道当时正在键入的内容,但如果您需要扩展代码,请在几年后说出来。你会错过从void *a *b *投射的几个地方,你会花很多时间调试正在进行的事情...... < / p>

现在我按照以下方式写这样的事情:

#include <stdio.h>


typedef struct header
{
    int jack;
    float jill;
} h;

typedef struct one
{
    struct header header;

    /* what ever you like */
}a;

typedef struct two
{
    struct header header;

    char something;
    int something1;

    /* and even more... */
}b;


void printJack(void *pStruct)
{
    printf("jack: %d\n", ((struct header *)pStruct)->jack);
}


/*
**    main
*/
int main(void)
{
    a first;
    b second;
    void *z;

    first.header.jack = 5;
    second.header.jack = 4892;

    printJack(&first);
    printJack(&second);

    v = &first;
    printJack(v);

    return (0);
}

正如您已经注意到我已宣布新的struct header,其涵盖了struct onestruct two的公共部分。而不是将void *转换为a *b * a&#34;常见&#34;转换为struct header *(或h *)已完成。

通过这样做,您可以轻松扩展&#34;共同的属性&#34;结构或您可以使用此标头实现更多结构,函数printJack仍然可以工作。此外,不再需要属性type,因此更容易调用printJack。您甚至可以更改jack的类型,而无需在代码中的各个位置更改它。

但请记住,struct header需要是您使用此机制的结构的第一个元素。否则你会得到一些惊喜,因为你使用的内存不包含struct header的数据......