簡體   English   中英

qsort中的compare函數如何工作?

[英]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 ); 
}

什么abqsort的文檔中清楚地說明:這些是指向必須比較的數組元素的指針。

在這種情況下,比較函數知道數組元素的類型為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*以便它可以與任何數據類型一起使用。 因此,為了獲得實際的元素值,必須將aint*然后解除引用 - 因此, *(int*)a 函數必須返回一個負值,如果a是前放置b如果,正值b是前放置a或零,如果它並不重要的首先被放置(這通常是當元件的情況下等於)。 在這種特殊情況下,因為我們與數字打交道,只需減去值b從價值a是足夠的,如果我們想在最大的數先走。

來自http://en.cppreference.com/w/cpp/algorithm/qsort

如果第一個參數小於第二個參數,則cmp函數返回負整數值;如果第一個參數大於第二個參數,則返回正整數值;如果參數相等,則返回零。

該函數采用void指針,因此qsort函數可以與任何數據類型一起使用。 但是在cmp函數中,必須顯式地將指針強制轉換為實際的數據類型。

ab作為整數進行比較 - 它們必須作為void *傳入,但在最終被引用之前被轉換為int * 至於返回值,它將是正數,負數或零,所有這些都將在排序函數中考慮。

qsort會給它需要與cmpfunc進行比較的每一對,並使用它的返回值來查看哪一個更大,然后相應地對數組進行排序。

基本上,如果比較函數返回肯定結果,則意味着第一個參數大於第二個參數。 同樣,如果它返回負數,那么第二個參數更大。

在示例中,我們要對整數進行排序。 因此,當我們比較給定數組的兩個元素時,我們需要決定哪一個更大。 為了比較這些,簡單的減法操作就足夠了,因為當a更大時結果為正,如果a和b相等則結果為0,如果b更大則結果為負。

暫無
暫無

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

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