如何将 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);

备注:

  1. 指针参数可以隐式转换回 void*,无需显式转换
  2. 任何指针 T* 这样 sizeof(T)==1 将正常工作:char 有点传统,uint8 也可以