如何将 void 指针传递给 C 中的函数?
How can I pass void pointer to function in C?
我有排序功能。我正在将参数传递给这个函数,例如:
double tab[] = {-46, -81, 89, -13, -24, -65, 78, -32, -92, -43, 58, -48, 87, 31, 81};
int res = sort(tab, 15, sizeof(double), comp_double);
然后在排序函数中,我想将选项卡中的两个元素传递给比较函数。但是在算术运算中使用了类型为(void *)的指针有错误。
typedef int(*f)(const void*, const void*);
int sort(void *ptr, int N, int sizeof_element, f f);
我正在写关于排序函数内部的这一行:
comp_double((void *)(ptr + j), (void *)(ptr + j + 1))
我的问题是如何从选项卡传递 comp_double 函数具体数字。
我无法更改函数的声明。
编辑:
所以我的 comp_double 功能很好。正如我所说,我无法更改我的函数声明。我必须使用 sort 函数对数组进行排序,所以我必须使用我的 comp 函数。但是我不知道如何给它传递参数。
int comp_double(const void *ptr1, const void *ptr2){
if(ptr1 == NULL || ptr2 == NULL){
return 100;
}
if(*(double *)ptr1 > *(double *)ptr2){
return 1;
}
else if(*(double *)ptr1 < *(double *)ptr2){
return -1;
}
return 0;
}
int sort(void *ptr, int N, int sizeof_element, f function){
if(ptr == NULL || N <= 0 || sizeof_element <= 0 || function == NULL){
return 1;
}
if(function == comp_double){
for(int i = 0; i < N; i++){
for(int j = 0; j < N - 1; j++){
if(comp_double((void *)(ptr + j), (void *)(ptr + j + 1)) == 1){
double temp = 0;
temp = *(double *)(ptr + j);
*(double *)(ptr + j) = *(double *)(ptr + j + 1);
*(double *)(ptr + j + 1) = temp;
}
}
}
}
return 0;
}
这是我的错误:
comparators.c: In function ‘sort’:
comparators.c:12:45: error: pointer of type ‘void *’ used in arithmetic [-Werror=pointer-arith]
if(comp_double((void *)(ptr + j), (void *)(ptr + j + 1)) == 1)
很遗憾,您没有提供足够的代码来在您的代码中显示它。
您将需要填空。
要调用传过来的比较函数,需要自己算一下:
int sort(void *ptr, int N, int sizeof_element, f f)
{
uint8*p = ptr;
// ... Doing the sorting things...
//Assuming you want to compare element j and k in the array
int result = f( &p[j*sizeof_element], &p[k*sizeof_element] );
// ... Doing more sorting things
}
我想添加您更新后的代码,您不能直接在 sort
函数中调用 comp_double
。这就是 f
的用途。
您收到的错误消息是因为您无法对 void*
进行指针运算,因为 void
没有大小。 (除了一些 GCC 扩展)
How can I pass void pointer to function in C?
你已经是了,所以这不是你的问题。
I am writing about this line which is inside sort function:
comp_double((void *)(ptr + j), (void *)(ptr + j + 1))
好的,它不是传递 void*
你遇到的问题,而是对其进行指针运算。
原因是 void*
没有相关联的类型,因此编译器不知道 ptr+1
应该前进多少字节。如果您使用 char *ptr
,它将是一个字节。对于 double* ptr
它将是 sizeof(double)
字节等
由于我们无法将 ptr
转换为正确的类型(每次调用都可能不同,这使得该函数可重用),我们必须手动执行此指针运算:
char *base = (char *)ptr;
...
comp_double(base + j*sizeof_element, base + (j + 1)*sizeof_element);
备注:
- 指针参数可以隐式转换回
void*
,无需显式转换
- 任何指针
T*
这样 sizeof(T)==1
将正常工作:char
有点传统,uint8
也可以
我有排序功能。我正在将参数传递给这个函数,例如:
double tab[] = {-46, -81, 89, -13, -24, -65, 78, -32, -92, -43, 58, -48, 87, 31, 81};
int res = sort(tab, 15, sizeof(double), comp_double);
然后在排序函数中,我想将选项卡中的两个元素传递给比较函数。但是在算术运算中使用了类型为(void *)的指针有错误。
typedef int(*f)(const void*, const void*);
int sort(void *ptr, int N, int sizeof_element, f f);
我正在写关于排序函数内部的这一行:
comp_double((void *)(ptr + j), (void *)(ptr + j + 1))
我的问题是如何从选项卡传递 comp_double 函数具体数字。 我无法更改函数的声明。
编辑: 所以我的 comp_double 功能很好。正如我所说,我无法更改我的函数声明。我必须使用 sort 函数对数组进行排序,所以我必须使用我的 comp 函数。但是我不知道如何给它传递参数。
int comp_double(const void *ptr1, const void *ptr2){
if(ptr1 == NULL || ptr2 == NULL){
return 100;
}
if(*(double *)ptr1 > *(double *)ptr2){
return 1;
}
else if(*(double *)ptr1 < *(double *)ptr2){
return -1;
}
return 0;
}
int sort(void *ptr, int N, int sizeof_element, f function){
if(ptr == NULL || N <= 0 || sizeof_element <= 0 || function == NULL){
return 1;
}
if(function == comp_double){
for(int i = 0; i < N; i++){
for(int j = 0; j < N - 1; j++){
if(comp_double((void *)(ptr + j), (void *)(ptr + j + 1)) == 1){
double temp = 0;
temp = *(double *)(ptr + j);
*(double *)(ptr + j) = *(double *)(ptr + j + 1);
*(double *)(ptr + j + 1) = temp;
}
}
}
}
return 0;
}
这是我的错误:
comparators.c: In function ‘sort’:
comparators.c:12:45: error: pointer of type ‘void *’ used in arithmetic [-Werror=pointer-arith]
if(comp_double((void *)(ptr + j), (void *)(ptr + j + 1)) == 1)
很遗憾,您没有提供足够的代码来在您的代码中显示它。 您将需要填空。
要调用传过来的比较函数,需要自己算一下:
int sort(void *ptr, int N, int sizeof_element, f f)
{
uint8*p = ptr;
// ... Doing the sorting things...
//Assuming you want to compare element j and k in the array
int result = f( &p[j*sizeof_element], &p[k*sizeof_element] );
// ... Doing more sorting things
}
我想添加您更新后的代码,您不能直接在 sort
函数中调用 comp_double
。这就是 f
的用途。
您收到的错误消息是因为您无法对 void*
进行指针运算,因为 void
没有大小。 (除了一些 GCC 扩展)
How can I pass void pointer to function in C?
你已经是了,所以这不是你的问题。
I am writing about this line which is inside sort function:
comp_double((void *)(ptr + j), (void *)(ptr + j + 1))
好的,它不是传递 void*
你遇到的问题,而是对其进行指针运算。
原因是 void*
没有相关联的类型,因此编译器不知道 ptr+1
应该前进多少字节。如果您使用 char *ptr
,它将是一个字节。对于 double* ptr
它将是 sizeof(double)
字节等
由于我们无法将 ptr
转换为正确的类型(每次调用都可能不同,这使得该函数可重用),我们必须手动执行此指针运算:
char *base = (char *)ptr;
...
comp_double(base + j*sizeof_element, base + (j + 1)*sizeof_element);
备注:
- 指针参数可以隐式转换回
void*
,无需显式转换 - 任何指针
T*
这样sizeof(T)==1
将正常工作:char
有点传统,uint8
也可以