[英]How does the compare function in qsort work?
我在網上找到了這個示例代碼,它解釋了qsort
函數的工作原理。 我無法理解比較函數返回的內容。
#include "stdlib.h"
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc (const void * a, const void * b) //what is it returning?
{
return ( *(int*)a - *(int*)b ); //What is a and b?
}
int main(int argc, _TCHAR* argv[])
{
int n;
printf("Before sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
qsort(values, 5, sizeof(int), cmpfunc);
printf("\nAfter sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
return 0;
}
int cmpfunc (const void * a, const void * b) //what is it returning?
{
return ( *(int*)a - *(int*)b ); //What is a and b?
}
相當於:
int cmpfunc (const void * a, const void * b) //what is it returning?
{
// qsort() passes in `void*` types because it can't know the actual types being sorted
// convert those pointers to pointers to int and deref them to get the actual int values
int val1 = *(int*)a;
int val2 = *(int*)b;
// qsort() expects the comparison function to return:
//
// a negative result if val1 < val2
// 0 if val1 == val2
// a positive result if val1 > val2
return ( val1 - val2 );
}
什么a
和b
在qsort
的文檔中清楚地說明:這些是指向必須比較的數組元素的指針。
在這種情況下,比較函數知道數組元素的類型為int
。 因此它將void *
指針強制轉換為int *
類型,並通過從第一個值中減去秒來執行指向的int
值的三態比較。
它適用於您的值集,但一般情況下使用減法進行三態比較是一種糟糕的編程習慣,因為它容易溢出。 此外,示例代碼中的函數不必要地拋棄了指向值的常量。
一個更好的選擇是
int cmpfunc(const void *a, const void *b)
{
const int *A = a, *B = b;
return (*A > *B) - (*A < *B);
}
每當排序算法需要找出兩個元素中的哪一個應該放在另一個之前時,它將調用比較函數並將指針傳遞給兩個元素。 由於您要對int
值進行排序,因此指針實際上是指向int
指針,但簽名必須為void*
以便它可以與任何數據類型一起使用。 因此,為了獲得實際的元素值,必須將a
為int*
然后解除引用 - 因此, *(int*)a
。 函數必須返回一個負值,如果a
是前放置b
如果,正值b
是前放置a
或零,如果它並不重要的首先被放置(這通常是當元件的情況下等於)。 在這種特殊情況下,因為我們與數字打交道,只需減去值b
從價值a
是足夠的,如果我們想在最大的數先走。
來自http://en.cppreference.com/w/cpp/algorithm/qsort
如果第一個參數小於第二個參數,則cmp
函數返回負整數值;如果第一個參數大於第二個參數,則返回正整數值;如果參數相等,則返回零。
該函數采用void
指針,因此qsort
函數可以與任何數據類型一起使用。 但是在cmp
函數中,必須顯式地將指針強制轉換為實際的數據類型。
a
和b
作為整數進行比較 - 它們必須作為void *
傳入,但在最終被引用之前被轉換為int *
。 至於返回值,它將是正數,負數或零,所有這些都將在排序函數中考慮。
qsort會給它需要與cmpfunc進行比較的每一對,並使用它的返回值來查看哪一個更大,然后相應地對數組進行排序。
基本上,如果比較函數返回肯定結果,則意味着第一個參數大於第二個參數。 同樣,如果它返回負數,那么第二個參數更大。
在示例中,我們要對整數進行排序。 因此,當我們比較給定數組的兩個元素時,我們需要決定哪一個更大。 為了比較這些,簡單的減法操作就足夠了,因為當a更大時結果為正,如果a和b相等則結果為0,如果b更大則結果為負。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.