qsort:轉(zhuǎn)換比較器函數(shù)本身還是比較器函數(shù)體中的參數(shù)?
在c中使用qsort:cast有兩種明顯的方法操作員:int cmp(const void*v1,const void*v2){const double*d1=v1,*d2=v2;:}qsort(p,n,sizeof(double),cmp)
解答動(dòng)態(tài)
應(yīng)避免后一種情況,因?yàn)樗鼰o效。
要使兩個(gè)函數(shù)類型兼容,返回類型必須兼容,相應(yīng)的參數(shù)類型必須兼容。const void*與const double*不兼容,因此函數(shù)類型不兼容。通過不兼容的指針類型調(diào)用函數(shù)會(huì)導(dǎo)致未定義的行為。請(qǐng)注意,僅僅因?yàn)閮蓚(gè)類型可以隱式轉(zhuǎn)換,并不意味著它們是兼容的。以const double*和const void*為例,這兩種類型之間的轉(zhuǎn)換可以在沒有強(qiáng)制轉(zhuǎn)換的情況下執(zhí)行,但是這兩種類型的表示形式不必相同。
這意味著const double*傳遞給函數(shù)的方式可能不同于const void*傳遞給函數(shù)的方式。因此,通過調(diào)用int(*)(const double*,const double*)類型的函數(shù),就像調(diào)用int(*)(const void*,const void*)類型的函數(shù)一樣,參數(shù)可能會(huì)以錯(cuò)誤的方式傳遞。
x64和ARM系統(tǒng)通常會(huì)對(duì)所有指針類型使用相同的表示形式,但您可以不使用前者,但這仍然無法保證,F(xiàn)代編譯器通常會(huì)假定不發(fā)生未定義的行為,并基于此事實(shí)執(zhí)行優(yōu)化。
前一種情況是正確的方法,因?yàn)楹瘮?shù)的簽名與qsort函數(shù)所期望的兼容。
作為附錄,調(diào)用qsort還有另一種策略:創(chuàng)建一個(gè)中介qsort所需的原型函數(shù),該原型函數(shù)調(diào)用啟用類型的比較函數(shù)。
#includegt;#includegt;static int double\u cmp(const double*d1,const double*d2){return(*d1gt;*d1);}static int double\u void\u cmp(const void*v1,constvoid*v2){return double_cmp(v1,v2);}int main(void){double p[]={2.18,6.28,3.14,1.20,2.72,0.58,4.67,0.0,1,1.68};const size_t n=sizeof p/sizeof*p;size_t i;qsort(p,n,sizeof*p,lt;n;i++)printf(quot;,i?quot;:quot;\n";,stdout);return EXIT_SUCCESS;} 盡管這有它自己的問題,但是可以使用double_cmp作為其他非qsort事物的比較。而且,它不需要任何強(qiáng)制轉(zhuǎn)換或顯式賦值,根據(jù)我對(duì)iso98996.3.2.3的解釋,
A指向void的指針可以轉(zhuǎn)換為或從指向任何不完整或?qū)ο箢愋偷闹羔槨?br/>除了dbush極好的答案之外,還應(yīng)該注意比較函數(shù)不應(yīng)該簡單地返回值的差(*d1-*d2)。這不適用于浮點(diǎn)值,也不適用于int值,因?yàn)闇p法可能會(huì)溢出。
這里有一個(gè)遞增順序的實(shí)現(xiàn),適用于所有數(shù)字類型:
int cmp(const void*v1,const void*v2){const int* =v1,*
=v2;對(duì)于浮點(diǎn)類型,返回(* lt;*
);} ,可能需要對(duì)NaN值進(jìn)行特殊處理需要:
//按遞增值排序,在numbersint cmp(const void*v1,const void*v2){const double* =v1,*
=v2;if(isnan(* )){返回isnan(*
)?0:1;}else if(isnan(*
)){return-1;}else{return(* lt;*
);}}- End
免責(zé)聲明:
本頁內(nèi)容僅代表作者本人意見,若因此產(chǎn)生任何糾紛由作者本人負(fù)責(zé),概與琴島網(wǎng)公司無關(guān)。本頁內(nèi)容僅供參考,請(qǐng)您根據(jù)自身實(shí)際情況謹(jǐn)慎操作。尤其涉及您或第三方利益等事項(xiàng),請(qǐng)咨詢專業(yè)人士處理。