在C中的动态数组中插入元素的问题
Troubles with inserting elements in dynamic array in C
我有一个具有此结构的动态数组:
typedef struct vector_struct {
size_t e_sz;
char e_type;
#define V_INT 1
#define V_DOUBLE 2
#define V_CHAR 3
#define V_FLOAT 4
unsigned no_e;
unsigned cur_cap;
void* e_array;
}* vector_type;
其中no_e是大小,cur_cap是容量,e_sz是数组中元素的大小,e_array是空指针。
我必须完成一个 push_back 函数,该函数必须适用于上面定义的 4 种不同类型。
void v_push_back(vector_type v, void* new_val){
if( v->no_e >= v->cur_cap ){
/*** reallocate a larger array ***/
v->cur_cap += (v->cur_cap) ? v->cur_cap : 2;
v->e_array = realloc(v->e_array, v->cur_cap*(v->e_sz))
}
/*** copy new_val in the array at index v->no_e ***/
/*** TO BE DONE START ***/
if(v->e_type == 1)
memcpy(((int*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 2)
memcpy(((double*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 3)
memcpy(((char*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 4)
memcpy(((float*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
/*** TO BE DONE END ***/
(v->no_e)++;
}
此函数适用于 char,但它似乎没有插入 int 或 double。
我找不到代码中的错误。
... + v->no_e*(v->e_sz)
是错误的。您已经转换为适当的类型,因此如果您对项目数组执行 +
,您将获得该特定类型的指针算法。只做 ... + v->no_e
就足够了,因为项目大小是基于指向的类型隐式存在的。这就是为什么 1 字节字符可以工作但没有别的。
指针算法而不是数组索引通常更难阅读。我会像这样重写代码:
void* item;
switch(v->e_type)
{
case V_INT: item = &( (int*) v->e_array )[v->no_e]; break;
case V_DOUBLE: item = &( (double*) v->e_array )[v->no_e]; break;
case V_CHAR: item = &( (char*) v->e_array )[v->no_e]; break;
case V_FLOAT: item = &( (float*) v->e_array )[v->no_e]; break;
}
memcpy(item, new_val, v->e_sz);
注意这里和那里的一些空格如何使重复的代码更具可读性,并最大限度地减少与打字错误相关的错误的可能性。另请注意,此代码利用 [] 具有比 &.
更高的运算符优先级
在这种特定情况下,指针算术替代方案实际上也很不错。许多人可能会发现这更具可读性:
void* item;
switch(v->e_type)
{
case V_INT: item = (int*) v->e_array + v->no_e; break;
case V_DOUBLE: item = (double*) v->e_array + v->no_e; break;
case V_CHAR: item = (char*) v->e_array + v->no_e; break;
case V_FLOAT: item = (float*) v->e_array + v->no_e; break;
}
memcpy(item, new_val, v->e_sz);
我有一个具有此结构的动态数组:
typedef struct vector_struct {
size_t e_sz;
char e_type;
#define V_INT 1
#define V_DOUBLE 2
#define V_CHAR 3
#define V_FLOAT 4
unsigned no_e;
unsigned cur_cap;
void* e_array;
}* vector_type;
其中no_e是大小,cur_cap是容量,e_sz是数组中元素的大小,e_array是空指针。
我必须完成一个 push_back 函数,该函数必须适用于上面定义的 4 种不同类型。
void v_push_back(vector_type v, void* new_val){
if( v->no_e >= v->cur_cap ){
/*** reallocate a larger array ***/
v->cur_cap += (v->cur_cap) ? v->cur_cap : 2;
v->e_array = realloc(v->e_array, v->cur_cap*(v->e_sz))
}
/*** copy new_val in the array at index v->no_e ***/
/*** TO BE DONE START ***/
if(v->e_type == 1)
memcpy(((int*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 2)
memcpy(((double*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 3)
memcpy(((char*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 4)
memcpy(((float*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
/*** TO BE DONE END ***/
(v->no_e)++;
}
此函数适用于 char,但它似乎没有插入 int 或 double。 我找不到代码中的错误。
... + v->no_e*(v->e_sz)
是错误的。您已经转换为适当的类型,因此如果您对项目数组执行 +
,您将获得该特定类型的指针算法。只做 ... + v->no_e
就足够了,因为项目大小是基于指向的类型隐式存在的。这就是为什么 1 字节字符可以工作但没有别的。
指针算法而不是数组索引通常更难阅读。我会像这样重写代码:
void* item;
switch(v->e_type)
{
case V_INT: item = &( (int*) v->e_array )[v->no_e]; break;
case V_DOUBLE: item = &( (double*) v->e_array )[v->no_e]; break;
case V_CHAR: item = &( (char*) v->e_array )[v->no_e]; break;
case V_FLOAT: item = &( (float*) v->e_array )[v->no_e]; break;
}
memcpy(item, new_val, v->e_sz);
注意这里和那里的一些空格如何使重复的代码更具可读性,并最大限度地减少与打字错误相关的错误的可能性。另请注意,此代码利用 [] 具有比 &.
更高的运算符优先级在这种特定情况下,指针算术替代方案实际上也很不错。许多人可能会发现这更具可读性:
void* item;
switch(v->e_type)
{
case V_INT: item = (int*) v->e_array + v->no_e; break;
case V_DOUBLE: item = (double*) v->e_array + v->no_e; break;
case V_CHAR: item = (char*) v->e_array + v->no_e; break;
case V_FLOAT: item = (float*) v->e_array + v->no_e; break;
}
memcpy(item, new_val, v->e_sz);