结构指针转换 [英] Struct pointer casts

查看:67
本文介绍了结构指针转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现这样的链接列表:

I'm trying to implement a linked list like this:

typedef struct SLnode
{
    void* item;
    void* next;
} SLnode;

typedef struct DLnode
{
    void* item;
    void* next;
    struct DLnode* prev;
} DLnode;

typedef struct LinkedList
{
    void* head; /*SLnode if doubly_linked is false, otherwise DLnode*/
    void* tail; /* here too */
    bool doubly_linked;
} LinkedList;

我想这样访问它:

void* llnode_at(const LinkedList* ll, size_t index)
{
    size_t i;
    SLnode* current;

    current = ll->head;

    for(i = 0; i < index; i++)
    {
        current = current->next;
    }

    return current;
}

所以我的问题是:


  • 只要我仅访问公共成员,我是否允许在这些结构之间进行转换?我对此有不同的看法。

  • 我还可以做相应类型的下一个指针吗?或者是UB,然后在我的示例函数中使用它,以防它真的是DLnode?

如果这不起作用,还有其他类似的方法吗?我了解到工会可能会起作用,但是此代码也应该在C89中运行,并且afaik读取的UB成员不同于上次写入的工会成员是UB。

In case this doesn't work, are there any other ways of doing something like this? I read that unions might work, but this code should also run in C89, and afaik reading a different union member than last written to is UB there.

推荐答案

因此,您尝试在C中构建子类。一种可能的方法是使基本结构成为子结构的第一个元素,因为在这种情况下,C标准明确允许在这两个结构之间来回转换。类型:

So you are trying to build subclasses in C. A possible way is to make the base struct to be the first element of the child struct, because in that case C standard explicitely allows casting back and forth between those 2 types:


6.7.2.1结构和联合说明符

6.7.2.1 Structure and union specifiers

§13 ...指向$ b $的指针经过适当转换的b结构对象指向其初始成员(或者,如果该成员是
位域,则指向它所在的单元),反之亦然...

§ 13 ... A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa...

缺点是您需要强制转换为基类才能访问其成员:

The downside is that you need a cast to the base class to access its members:

示例代码:

typedef struct SLnode
{
    void* item;
    void* next;
} SLnode;

typedef struct DLnode
{
    struct SLnode base;
    struct DLnode* prev;
} DLnode;

然后可以使用该方式:

    DLnode *node = malloc(sizeof(DLnode));
    ((SLnode*) node)->next = NULL;             // or node->base.next = NULL
    ((SLnode *)node)->item = val;
    node->prev = NULL;

这篇关于结构指针转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆