1

作为 C 语言的初学者,我正在努力解决一个晦涩难懂的问题,因为我找不到这个特定问题的解决方案,所以我想问你以下问题:目前我正在尝试理解 void 指针及其算术运算。我试图编写一个通用函数,它接受一个指向数组的 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

但是有了这个解决方案,我还必须检查其他数据类型,所以你给我一个提示会非常好。

谢谢!

-matzui

4

2 回答 2

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

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

因为您确切知道要移动指针的字节数,所以可以将 is 转换为char *(char = 1 byte),并将字节数添加到其中。

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

于 2015-01-24T21:49:53.630 回答
1

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

于 2015-01-24T21:43:56.790 回答