在c中使用结构的地址和指针访问结构的第一个元素

时间:2019-01-16 15:14:12

标签: c linux

我注意到struct地址和第一个元素地址看起来是相同的。 因此,我尝试使用主struct的地址访问struct的第一个元素。 但是我遇到了错误。

与显示器的参数1兼容。

我在这里犯什么错误?

代码

#include <stdio.h>
#include <stdlib.h>
#define BASE(class) *(&class)

struct animal {
    int walk;
    int hear;
};

struct bird {
    struct animal *base;
    int fly;
};

void display(struct animal *common) {
    printf("All animal details hear=%d  walk=%d ", common->hear, common->walk);
}

int main() {
    struct bird peacockptr;
    struct animal base;
    base.hear = 1;
    base.walk = 1;
    peacockptr.base = &base;

    struct bird *pecock = &peacockptr;
    pecock->fly = 1;

    printf("base address using peacock struct %d\n",
       BASE(peacockptr));  // both are printing same address
    printf("base address animal %d\n",
       &base);  // both are printing same address

    display(&base);     // here it work
    display(BASE(peacockptr));  // getting error
}

2 个答案:

答案 0 :(得分:3)

的确,结构的地址与其第一个成员的地址相同。但是,它们具有不同的类型。一个具有类型struct animal *,另一个具有类型struct base *

在这种情况下,您可以在两者之间进行转换,但是您需要进行显式强制转换。

display((struct animal *)BASE(peacockptr));   

另外,关于定义BASE宏的方式:

#define BASE(class) *(&class)

*&运算符相互抵消,因此实际上是无操作的。 BASE(peacockptr)等同于peacockptr

现在强制转换失败的原因是,您将peacockptr定义为实例,将pecock定义为指针 ,即您对命名感到困惑。切换名称以反映用法:

struct bird peacock;
struct animal base;
base.hear=1;
base.walk=1;
peacock.base= &base;

struct bird *peacockptr =&peacock;
peacockptr->fly=1;

答案 1 :(得分:2)

如前所述,当操作符取消指针时,您可以删除BASE宏。

我清除并更正了您的代码,并解释了哪里出了问题:

#include <stdio.h>
#include <string.h>

struct animal
{
    int walk;
    int hear;
};

struct bird
{
    struct animal *base;
    int fly;
};

void display(struct animal *common)
{
    printf("All animal details hear=%d  walk=%d\n",common->hear, common->walk);
}

int main()
{
    struct bird peacock; // removed ptr suffix, since it is not a pointer
    struct animal base ;

    base.hear=1;
    base.walk=1;

    peacock.base= &base;

    struct bird *peacockptr = &peacock;
    peacockptr->fly=1;

    printf("base address using peacock struct %p\n",  (void *)*(struct animal **)peacockptr); //This is the address of base using peackockptr
    printf("base address animal %p\n", (void *)&base); //This is the address of base

    display(&base);
    display(*(struct animal **)peacockptr);

    return 0;
}

请注意,peackock的地址等于结构的第一个元素struct animal *的地址。因此,您必须将peacockptr强制转换为struct animal **(因为它指向类型为struct animal *的第一个元素),然后对其取消引用以获取base的地址。