1. 程式人生 > >【C/C++】qsort函式的使用方法和細節

【C/C++】qsort函式的使用方法和細節

函式概述

qsort 為quick sort的簡寫,意為快速排序,主要用於對各種陣列的排序,在標頭檔案stdlib.h中。
因為陣列的元素可能是任何型別的,甚至是結構或者聯合,所以必須高數函式qsort如何確定兩個陣列元素哪一個“更小”,這就需要我們給出比較的規則,即什麼算大,什麼算小。
通過編寫比較函式可以為函式qsort提供這些資訊。當給定兩個指向陣列元素的指標p和q時,比較函式必須返回一個整數。如果*p小於*q,那麼返回的數為負數;如果*p等於*q,那麼返回0.如果*p大於*q,返回正數。

函式原型

void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *))

函式描述

函式的形式引數從左到右分別為:
指向要排序陣列的第一個元素的指標base(如果只是要對陣列的一段區域進行排序,那麼要是base指向這段區域的第一個元素。)在一般情況下,base就是陣列的名字;
nmemb是要排序元素的數量(不一定是陣列中元素的數量);
size是每個陣列元素的大小,用位元組來衡量;
compar為指向比較函式的指標。

比較函式的實現

比較函式的實現是qsort函式能否正確實現的重點。
編寫比較函式並沒有想象中的那麼容易。函式qsort要求它的形式引數型別為void *,但我們不能通過void *型的指標訪問陣列的成員;我們需要指向要比較元素的型別的指標。為了解決這個問題,我們將在比較函式內部把p與q賦給相應對應型別的指標變數。由於常量指標不能賦值給變數。所以在宣告對應指標變數時應該加上const關鍵字。

下面是一個比較整型陣列的比較函式的例子。

    int compare(const void *p, const void *q)
    {
        const int *p1 = p;
        const int *q1 = q;
        if (*p1 < *q1)
            return -1;
        else if (*p1 == *q1)
            return 0;
        else
            return 1;
}

當然除了把用const指標變數的方法,還可以使用強制型別轉換的方式來達到這個目的。

    int compare(const void *p,const void *q)
    {
        if(*(int *)p<*(int *)q)
            return -1;
        else if(*(int *)p==*(int *)q)
            return 0;
        else
            return 1;
    }

還可以進一步精簡

    int compare(const void *p,const void *q)
    {
          return *(int *)p-*(int *)q;
    }

需要注意的點:比較元素是指標的比較函式的實現。

如果待比較的元素是指標(雖然我們一般不會比較指標的大小,但是我們經常需要對指標代表的空間比較大小,比如比較一個字串陣列的大小,每個字串都由一個指標代表),那麼比較函式的實現就比較麻煩了。
首先我們需要明確的是,比較函式中的兩個指標必須要指向需要比較的兩個元素。如果這兩個元素是指標而不是一個實體,那麼這兩個指標應該是指向指標的指標。
這裡我們以一個比較字串的比較函式舉例:

    int compare(const void *p,const void *q)
    {
        return strcmp(*(char **)p,*(char **)q);  
    }