【问题标题】:C typecasting for structure pointers结构指针的 C 类型转换
【发布时间】:2021-04-07 03:39:03
【问题描述】:

在某些示例中对 C 中琐碎的侵入式容器的实现感到困惑。 我有结构:

struct List {
    struct Link* first;
    struct Link* last;
};

Link for 成为列表的节点:

struct Link {
    struct Link* pre;
    struct Link* suc;
}; 

一些用于在列表中存储指定值的伪节点:

struct Name {
    struct Link lnk;
    char* n;
};

在List中推送值的功能:

void push_back(struct List* lst, struct Link* p) {
    assert(lst);
    {
        struct Link* last = lst->last;
        if (last) {
            p->pre = last;          
            last->suc = p;                                      
        }
        else {
            lst->first = p;
            p->pre = 0;
        }
        lst->last = p;
        p->suc = 0;
    }
}

List的用法和样例:

int main() {

    int count = 0;
    struct List names;
    struct Link* curr;
    init(&names);

    push_back(&names, (struct Link*)make_name("Norah"));
    push_back(&names, (struct Link*)make_name("Annemarie"));
    push_back(&names, (struct Link*)make_name("Kris"));

    curr = names.first;
    for (; curr != 0; curr = curr->suc) {
        count++;
        printf("element %d: %s\n", count, ((struct Name*)curr)->n);
    }
    return 0;
}

问题是,在这个例子中类型转换是如何工作的?当sizeof(Link)==8sizeof(Name)==12 指针curr 指向为Name 类型分配的内存,该结构没有sucpre 成员,只有lnk 类型为Name 的对象(不是指针),并且在代码中没有任何主要访问权限为这个会员。

【问题讨论】:

  • 结构体的地址等价于它的第一个成员的地址。因此,如果你有一个结构Name,它总是有一个Link作为第一个成员,那么那个Name的地址也是那个NameLink成员的地址,并且可以被利用因此。只是不要用它做指针算术。编译器可以在成员之间随意推动填充和对齐调整,但绝不会在 first 成员之前。

标签: c struct casting


【解决方案1】:

它依赖于struct Linkstruct Name 的第一个字段这一事实。您可以假装struct Name* 指向的12 个字节实际上是一个8 字节struct Link,而忽略剩余的4 个字节。请参阅以下问题:

【讨论】:

    【解决方案2】:

    谢谢各位!我忘记了struct Link 有两个第一个成员,每个成员有 4 个字节。当struct Name 通过参数到达push_back() 时,函数就像struct Link 一样与他一起操作。因为struct Name 在头部有8 个字节的成员,函数只是放置关于sucpre 成员的数据在这 8 个字节中。我可以将 lnk 成员从 Name 替换为任何其他大小为 8 字节的数据。

    我有美好的一天!

    【讨论】:

      猜你喜欢
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 2015-07-13
      • 1970-01-01
      相关资源
      最近更新 更多