为什么这段代码使用* char作为缓冲区指针?

时间:2011-01-31 00:55:48

标签: c pointers char

在寻找要重用的循环缓冲区代码时,我遇到了使用char的问题,这让我很困惑

typedef struct CircularBuffer
{
    void *buffer;     // data buffer
    void *buffer_end; // end of data buffer
    size_t capacity;  // maximum number of items in the buffer
    size_t count;     // number of items in the buffer
    size_t sz;        // size of each item in the buffer
    void *head;       // pointer to head
    void *tail;       // pointer to tail
} CircularBuffer;

void cb_push_back(CircularBuffer *cb, const void *item)
{
    if(cb->count == cb->capacity)
        // handle error
        memcpy(cb->head, item, cb->sz);

    ////////////// here's the part I don't understand //////////
    cb->head = (char*)cb->head + cb->sz;
    //////////////////////////////////////////////////////////

    if(cb->head == cb->buffer_end)
        cb->head = cb->buffer;
    cb->count++;
}

为什么将此void指针强制转换为char?这是某种C语言(我有很大的限制吗)吗?一种方便的增加指针的方法吗?

在一些不同的缓冲区代码中再次使用char作为位置指针:

/**< Circular Buffer Types */
typedef unsigned char INT8U;
typedef INT8U KeyType;
typedef struct
{
    INT8U writePointer; /**< write pointer */
    INT8U readPointer;  /**< read pointer */
    INT8U size;         /**< size of circular buffer */
    KeyType keys[0];    /**< Element of ciruclar buffer */
} CircularBuffer;

同样,这看起来像C程序员所知道的一些方便的技巧,如果指针很容易操作,那么它们很容易操作。但我真的只是猜测。

4 个答案:

答案 0 :(得分:6)

如果要以一个字节的步长移动指针,转换为char *是为了使指针算法正确执行;这总是有效的,因为根据定义,char具有1个字节的大小。相反,使用void *指针的指针算法不是由C标准定义的,因为void没有指定单个项目的大小。

另一个常见的C语言(与此相关)是当你想以“原始字节”访问某些内存时使用unsigned char *unsigned类型允许你访问每个字节的无符号值而不需要铸);它经常用typedef ed(类似于typedef unsigned char byte;的内容)来明确表示你不想将内存解释为字符,而是将其解释为原始字节。

答案 1 :(得分:5)

char的大小为一个字节,因此当您想要将某些内存区域简单地作为字节数组进行操作时,会使用它(或signed charunsigned char)。

答案 2 :(得分:3)

Void指针只指向一个值,并且没有类型信息。因此无法对void指针执行添加。将其转换为其他类型需要指针算法。这里将void *转换为char *然后添加cb-&gt; sz,假设char的大小为1,则按大小字节向前移动。

答案 3 :(得分:1)

强制转换启用指针算术;没有它,因为cb->head的类型为void*,所以表达式cb->head + cb->sz没有意义。

指针强制转换为char*后,指针添加(char*)cb->head + cb->sz表示“对象cb->size字节的地址超过cb->head指向的位置。