11

为了更好地理解这篇文章中给出的答案,有人可以向我解释以下循环缓冲区实现是否可行,如果不可行,为什么不可以。

#define CB_TYPE_CHAR     0
#define CB_TYPE_FLOAT    1

...

typedef struct CBUFF
{
    uint16 total;       /* Total number of array elements */
    uint16 size;        /* Size of each array element */
    uint16 type;        /* Array element type */
    uint16 used;        /* Number of array elements in use */
    uint16 start;       /* Array index of first unread element */
    void *elements;     /* Pointer to array of elements */
} CBUFF;

...

void cbRead(CBUFF *buffer, void *element)
{
    if (buffer->type == CB_TYPE_CHAR)
    {
    /* The RHS of this statement is the problem */
        *(char*)element = *(buffer->elements[buffer->start]);
    }

    /* Other cases will go here */

    buffer->start = (buffer->start + 1) % buffer->total;

    --buffer->used;
}

我知道 LHS 必须强制转换为 char 以便我可以取消引用 void 指针。我也明白这个代码片段:

buffer->elements[buffer->start]

给出 elements 数组的 'buffer->start' 元素的地址,我也想取消引用以获取该地址的内容。或者至少这是我从 K&R 那里得到的。

鉴于这一切,我如何告诉编译器该地址处的内存内容是一个字符,并且可以取消引用它?这里发生了一些事情,我只是不明白。

4

2 回答 2

14

buffer->elements也是 avoid *所以你需要先转换它,然后才能对它做任何事情:

*(char*)element = ((char *)buffer->elements)[buffer->start];
于 2012-12-04T01:48:08.947 回答
5

鉴于这一切,我如何告诉编译器该地址处的内存内容是一个字符,并且可以取消引用它?

好吧,您已经在该行的 LHS 上完成了它:

*(char*)element = *(buffer->elements[buffer->start]);

为了解除防御buffer->elements[n],您还需要使用它。

*(char*)element = *((char*)buffer->elements)[buffer->start];

现在的问题是该演员阵容是否正确。我不能告诉你,因为你没有发布buffer->elements.

于 2012-12-04T01:35:18.610 回答