【问题标题】:Troubles with inserting elements in dynamic array in C在 C 中的动态数组中插入元素的问题
【发布时间】:2020-09-30 20:56:31
【问题描述】:

我有一个带有这个结构的动态数组:

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 是 void 指针。

我必须完成一个 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。 我在代码中找不到错误。

【问题讨论】:

    标签: c dynamic-arrays push-back


    【解决方案1】:

    ... + 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);
    

    【讨论】:

    • 非常感谢我会试试你的解决方案
    • 我试过了,但我有一个不同的问题。字符直到工作正常,但是当我尝试打印数组时,我没有在整数中有一串零,而是有随机数。
    • 感谢您花时间解决问题。这是打印功能中的一个问题
    猜你喜欢
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2023-03-09
    • 2013-06-01
    • 2017-02-27
    相关资源
    最近更新 更多