C 创建大小为n字节的数据类型

C 创建大小为n字节的数据类型,c,pointers,types,typedef,C,Pointers,Types,Typedef,我正在为C语言中的队列制作一个类似于弹性缓冲区的单文件头库。 我将数组作为void*和单个元素的大小传递给以下函数之一: void func(void*arr,size\u t itemsize); 在func()内部,我需要使用arr执行一些指针算法 我不能用void*做算术,所以我想我可以创建一个sizeitemsize的数据类型,我可以将arr转换为该类型,从而解决我的问题 我看到了被接受的,但是char*[]上的指针算法会按我想要的方式工作吗?如中所示,(char*[5])(arr)+

我正在为C语言中的队列制作一个类似于弹性缓冲区的单文件头库。
我将数组作为
void*
和单个元素的大小传递给以下函数之一:

void func(void*arr,size\u t itemsize);
func()
内部,我需要使用
arr
执行一些指针算法
我不能用
void*
做算术,所以我想我可以创建一个size
itemsize
的数据类型,我可以将
arr
转换为该类型,从而解决我的问题

我看到了被接受的,但是
char*[]
上的指针算法会按我想要的方式工作吗?如中所示,
(char*[5])(arr)+3
arr
过去15个字节,
和((char*[4])(arr))[6]
指向比
arr
过去24个字节

我需要在
func
中创建类型,我们可以看看如何创建。如果这是用于生产代码,只需使用GLib

首先,不要传递大小和指针。制作一个包含大小、数组和其他内容的结构。这允许您传递整个阵列。更简单,更不容易出错。下面是GLib是如何做到这一点的。重要的位是
数据
(guint8是or 1字节的GLib版本)和
elt_大小
(元素大小)。剩下的是肉汁

struct _GRealArray
{
  guint8 *data;
  guint   len;
  guint   alloc;
  guint   elt_size;
  guint   zero_terminated : 1;
  guint   clear : 1;
  gatomicrefcount ref_count;
  GDestroyNotify clear_func;
};
我们可以看看如何在索引中插入值。插入的肉在这里

memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
特殊的酱汁都在(元素位置)和(元素大小)宏中
g\u数组\u elt\u pos(数组,i)
复制
array[i]

#define g_array_elt_len(array,i) ((array)->elt_size * (i))
#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
数据存储为8位整数
g_array\u elt_len
通过将元素大小乘以索引来计算从数组开始的偏移量。然后
g\u array\u elt\u pos
将其添加到数组的开头

memcpy
有效地

memcpy(array[index_], data, (array->elt_size * len));
len
单位
array->elt\u size
大小从
data
复制到
array[i]

#define g_array_elt_len(array,i) ((array)->elt_size * (i))
#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))

查找元素需要类型转换。GLib使用宏为您处理此问题。它返回指向元素的指针

#define g_array_index(a,t,i)      (((t*) (void *) (a)->data) [(i)])
比如说

// Similar to double num = array[5]
// Expands to ((double*) (void *) array->data)[5]
double num = g_array_index(array, double, 5);

我被你问题的最后一句话弄糊涂了:但是20不是15,28不是24。Ie基地址+三个标量=基零数组的第四个元素。建议将数组定义并声明为无符号字符块,而不是void。接下来使用union{}代替类型转换和指针算法。对齐可能是另一个问题。因此,不需要传递基指针和元素大小,只需传递基指针和可变数组的字节大小,这意味着隐含的元素大小和类型。或者明确地通过这三个选项。

“按我想要的方式工作?”-->解释一下您希望指针数学如何工作。(我怀疑您想要类型
无符号字符[itemsize]
)。不相关,但对于大小,请使用
size\u t
作为类型。