假設我在 C 中有一個函式,它接受兩個 void 指標作為輸入,*a 和 *b 說,以及一個本身接受兩個 void 指標的函式(作為指標)。例如,該函式可能有如下宣告
arbitrary_type f(void *a, void *b,
arbitrary_type (*g)(void *, void *))
{
...
}
我們還假設該函式僅通過函式“g”起作用(可以將其視為“a”和“b”指向的變數的一種 getter 或 setter。)
請問這功能在技術上是能夠作用于任意三元組的(a, b, g)形式的指標type_a *a,type_b *b,rtype (\*g)(type_a *, type_b *)而不會引入錯誤?
uj5u.com熱心網友回復:
該函式在技術上是否能夠作用于 type_a *a, type_b *b, rtype (*g)(type_a *, type_b *) 形式的指標的任意三元組 (a, b, g)
是的。
不引入錯誤?
嗯,這取決于實際的代碼。請注意,void *指標消除了編譯器靜態檢查指標型別是否正確的能力。
這很大程度上取決于您要建模的介面,但您可以使用一個void *指標并讓用戶將兩個a b變數與一個結構“系結”在一起。
uj5u.com熱心網友回復:
該函式在技術上是否能夠作用于
(a, b, g)形式為type_a *a,type_b *b, 的任意三元組指標rtype (\*g)(type_a *, type_b *)
是的。
不引入錯誤?
哦。嗯......這一切都歸結為所g指向的任何內容的實施。不幸的是,一旦你使用void *任何東西,你就已經將任何型別安全的概念拋到了窗外,并進入了迎面而來的交通。
這幾乎就是qsort標準庫函式的作業方式——你將一個指向陣列的指標(作為 a void *)傳遞給它,元素的數量,每個元素的大小,以及一個指向比較兩個元素的函式的指標:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
如果你想對一個陣列進行int升序排序,你可以撰寫一個比較函式,如下所示:
int compare_int( const void *l, const void *r )
{
const int *a = l;
const int *b = r;
if ( *a < *b )
return -1;
else if ( *a > *b )
return 1;
return 0;
}
int main( void )
{
int arr[100];
...
qsort( arr, 100, sizeof arr[0], compare_int );
}
我們可以對陣列做同樣的事情double:
int compare_dbl( const void *l, const void *r )
{
const double *a = l;
const double *b = r;
if ( *a < *b )
return -1;
else if ( *a > *b )
return 1;
return 0;
}
int main( void )
{
double arr[100];
...
qsort( arr, 100, sizeof arr[0], compare_dbl );
}
的compare_int和compare_dbl功能是負責轉換引數為適當的型別進行比較。但問題是——沒有什么能阻止你這樣做:
int arr[100];
...
qsort( arr, 100, sizeof arr[0], compare_dbl );
沒有一種編譯時或運行時檢查來確保您已通過正確的比較函式來處理您嘗試排序的陣列型別。由于兩者qsort和您的比較函式都void *適用于所有內容,因此編譯器無法知道您為正在使用的陣列型別傳遞了錯誤的比較函式。
是的,您可以對任意型別的組合進行操作。不,您不能保證這樣做不會引入任何錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/407549.html
標籤:
下一篇:如何將陣列轉換為C中函式的引數?
