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

C 为什么这段代码使用*字符作为缓冲区指针?,c,pointers,char,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 item

在寻找可重用的循环缓冲区代码时,我遇到了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++;
}
为什么要将此空指针强制转换为字符?这是某种C语言习惯用法吗(我有非常有限的C语言经验)?一种方便的增加指针的方法

在一些不同的缓冲区代码中,位置指针也会使用字符:

/**< 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;
/**<循环缓冲区类型*/
typedef无符号字符INT8U;
typedef INT8U KeyType;
类型定义结构
{
INT8U写指针;/**<写指针*/
INT8U读取指针;/**<读取指针*/
INT8U大小;/**<循环缓冲区的大小*/
KeyType键[0];/**<循环缓冲区的元素*/
}循环缓冲器;

同样,这看起来像是C程序员知道的一种简便的技巧,指针如果是字符就很容易操作。但我真的只是猜测。

字符的大小是一个字节,所以当您想简单地将某个内存区域作为字节数组进行操作时,可以使用它(或
有符号字符
无符号字符
)。

无效指针只指向一个值,没有类型信息。因此,不可能对空指针执行加法。指针算法需要将其转换为其他类型。在这里,将void*强制转换为char*,然后添加cb->sz,假设char的大小为1,则按大小字节向前移动。

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


另一种常见的C语言习惯用法(与此相关)是,当您希望以“原始字节”的形式访问某些内存时,使用
unsigned char*
(类型
unsigned
允许您访问每个字节的unsigned值,而不使用强制转换);它还经常被使用
typedef
ed(类似于
typedef unsigned char byte;
)来更加清楚地表明,您不想将内存解释为字符,而是原始字节。

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


一旦指针被转换到
char*
,指针添加
(char*)cb->head+cb->sz
意味着“对象的地址
cb->size
字节超过
cb->head
点。

FYI:该类型称为
char*
,而不是
*char
。这是我第一次将结构的名称视为typedef的名称,这很奇怪……不需要假设。
sizeof(char)==1
是有保证的。那么就没有标准字节大小(heh)的数字类型了吗?