[英]C programming: void * argument is it really pointer to anything, can I pass function pointer there
[英]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);
筆記:
void*
,無需顯式執行T*
使得sizeof(T)==1
可以正常工作: char
有點傳統, uint8
也可以
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.