如何将通用 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
作为 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