簡體   English   中英

如何將 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 fucntion。 但我不知道如何向它傳遞參數。

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 擴展)

如何將 void 指針傳遞給 C 中的函數?

你已經是了,所以這不是你的問題。

我正在寫關於排序函數內部的這一行:

 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也可以

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM