2010-11-16 70 views
0

我是學生&我在書中查找了這個函數。它的工作原理應該如此,但我不太瞭解sortFunction()的內部工作原理,該工作被傳遞給qsort()函數。如果有人能詳細解釋它,請做。提前致謝。使用qsort()函數

#include<iostream> 
#include<stdlib.h> 

using namespace std; 

//form of sort function required by qsort() 
int sortFunction(const void *intOne,const void *intTwo); 

const int tableSize = 10; 

int main() 
{ 
    int i, table[tableSize]; 

    //fill the table with values 
    for(i = 0; i < tableSize; i++) 
    { 
     cout << "Enter value " << (i + 1) << " : "; 
     cin >> table[i]; 
    } 
    cout << "\n"; 

    //sort values 
    qsort((void*)table, tableSize, sizeof(table[0]), sortFunction); 

    //print the results 
    for(i = 0; i < tableSize; i++) 
    { 
     cout << "Value " << (i + 1) << " : " << table[i] << endl; 
    } 

    cout << "\nDone\n"; 

    return 0; 
} 

int sortFunction(const void *a, const void *b) 
{ 
    int intOne = *((int*)a); 
    int intTwo = *((int*)b); 

    if (intOne < intTwo) 
    { 
     return -1; 
    } 
    if (intOne == intTwo) 
    { 
     return 0; 
    } 

    return 1;  
} 
+1

'qsort'是一個C函數。 C++提供了遠遠優越的'std :: sort',您應該使用它。 – jalf 2010-11-16 05:26:05

回答

4

如果你看看到qsort實際通話...

qsort((void*)table, tableSize, sizeof table[0], sortFunction); 

...你會看到它提供了:

  • 一個void*地址和大小(以字節爲單位)整個數據數組進行排序,然後
  • 該數組中的一個數據元素的大小,然後
  • 指向比較函數「sortFunction」的指針。

沒有參數傳遞,使qsort知道元素的類型是什麼 - 即如何在任何單個的數據元素的各個位用來表示一些數據價值 - 所以沒有辦法qsort可以有意識比較兩個這樣的元素。當您提供...

int sortFunction(const void *a, const void *b) 
{ 
    int intOne = *((int*)a); 
    int intTwo = *((int*)b); 

...和qsort調用它,你得到兩個指針 - 他們到內存地址,但是當qsort電話sortFunction那些void指針仍然告訴你一無所知的數據元素類型,因爲qsort本身沒有洞察力傳遞。上面最後兩行代碼是你 - 協調qsort調用的程序員 - 重新應用了你一直以來關於數據元素類型的知識:在這種情況下,他們是int s,所以你將每個void*int*(使用(int*)a),然後取消引用int*以獲得內存地址爲aint。同樣爲b。這樣做,你已經恢復了這兩個數字,數字爲。然後,sortFunction的工作是指出如何排序完成時應該如何訂購。爲了表明a應該是第一個,sortFunction可以返回任何負值(例如-1);如果它們相同,則爲return 0;,並且如果b應該是第一個,則返回任何正值(例如1)。 qsort()接收該信息並使用它來確定如何在數據元素分類時對其進行混洗。

FWIW,C可以讓你表達一點更簡潔的...

return intOne < intTwo ? -1 : 
     intOne == intTwo ? 0 : 
     1; 

...或(更快,但依靠布爾比較結果是0和1,這可能會混淆一些程序員閱讀您的代碼)...

return (intOne > intTwo) - (intOne < intTwo); 

...或者,如果你確保以下不能在數學上小於INT_MIN(例如值環繞一個大的正數不恰當)...

return intOne - intTwo; 
+0

非常感謝,這非常有幫助。我希望得到像這樣的詳細答案。再次感謝。 – Ramila 2010-11-16 07:49:28

+0

@Ramila:不客氣。 – 2010-11-16 07:55:37

+0

我喜歡你在最後一行詳細說明代碼限制的方式。 :) – J3soon 2017-09-01 04:18:40

3

sortFunction實際上沒有做分類,它被用作一個比較功能,以確定一個元素是否應在排序的列表之前的另一個。

+0

感謝您的回答。 – Ramila 2010-11-16 07:52:29

3

你所謂的'sortFunction'通常稱爲比較器。它基本上告訴qsort()中的泛型排序代碼,判斷數組中的兩個元素是否比較等於(0),或者第一個參數是在第二個(< 0)之前排序,還是第二個參數(> 0)排序。

使用該信息加上每行的大小再加上數組中的行數和數組的起始位數,函數qsort()可以正確地對數據進行排序。

+0

謝謝,我很感激。 – Ramila 2010-11-16 07:51:12

0

正如您在documentation中看到的那樣,qsort函數將比較器作爲最後一個參數。這個函數用於實際比較參數(告訴哪一個應該首先在一個有序數組中)。

+2

比較器必須返回三態值(負值,零,正值),但您引用的比較返回布爾值。因此,它們不應該與'qsort()'一起使用。 – 2010-11-16 02:27:07

+0

男人,我吮吸。當然,他們只能用於排序,謝謝指出! – 2010-11-16 02:29:23

+0

感謝您的回答。 – Ramila 2010-11-16 07:50:04