如何将通用 void 数组拆分为 parts.c

How to split a generic void array into parts.c

作为 C 的初学者,我正在为一个晦涩难懂的问题而苦苦挣扎,因为我找不到解决这个特定问题的方法,所以我想问您以下问题: 目前我正在尝试了解 void 指针及其算术运算。我试图编写一个 通用函数 ,它接受一个指向数组的空指针、数组的长度和一个元素的大小,并将给定的数组拆分为两个不同的部分(list1 和 list2 ):

void split(void *array, int arrlen, int objsize)
{
// divide the arrlen and save the values
    int len_list1 = arrlen / 2;
    int len_list2 = arrlen - len_list1;

// Allocate memory for two temporary lists
    void *list1 = (void*)malloc(objsize * len_list1);
    void *list2 = (void*)malloc(objsize * len_list2);

    if (list1 == NULL || list2 == NULL)
    {
        printf("[ERROR]!\n");
        exit(-1);
    }

// list1 gets initialized properly with int and char elements
    memmove(list1, array, len_list1*objsize);           
    printf("list1:"); 
    print_arr(list1, len_list1);

// memmove((char*)list2, (char*)array+list_1_length, list_2_length*objsize); (*)
    memmove(list2, (int*)array+len_list1, len_list2*objsize);
    printf("list2:");
    print_arr(list2, len_list2);
}

我的问题如下: 如果我给这个函数一个 int 数组它会工作正常,但是如果我用一个 char 数组作为参数调用 split(),我必须...

memmove((char*)list2, (char*)array+list_1_length, list_2_length*objsize);
//memmove((int*)list2, (char*)array+list_1_length, list_2_length*objsize);

把注释行(*)去掉,才能得到相同的结果。一个解决方案肯定是编写一个 if-else 条件并测试 objsize:

if (objsize == sizeof(int))
    // move memory as in the 1st code snippet
else
    // move memory with the (int*) cast

但是如果使用这个解决方案,我还必须检查其他数据类型,所以非常感谢您给我一个提示。

谢谢!

-麻嘴

void 指针只是一个字大小的可解引用指针,不暗示特定的数据类型。因此,你不能用它做指针数学。要执行您想要执行的操作,请在您的函数中声明一个适当类型的指针,然后将其值设置为等于参数 void 指针的值。

memmove(list2, (int*)array+len_list1, len_list2*objsize);

在这里,您将 array 类型转换为 int *,并向其添加 len_list1。但是向指针添加一些东西,意味着它将乘以该指针数据类型的一个元素的大小。所以如果一个 int 是 4 个字节,你将 5 添加到一个 int * 变量,它将移动 20 个字节。

因为您确切知道要移动指针的字节数,所以您可以将 is 强制转换为 char *(char = 1 字节),然后将字节数添加到它。

因此,您可以使用 (char*)array+(len_list1*objsize)

而不是 (int*)array+len_list1