C 为什么这段代码使用*字符作为缓冲区指针?
在寻找可重用的循环缓冲区代码时,我遇到了char的用法,这让我很困惑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
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)的数字类型了吗?