void 指標的多型行為

qsort() 標準庫函式是一個如何使用空指標,以使一個單一的功能上大量各種不同型別的工作一個很好的例子。

void qsort (
    void *base,                                 /* Array to be sorted */
    size_t num,                                 /* Number of elements in array */
    size_t size,                                /* Size in bytes of each element */
    int (*compar)(const void *, const void *)); /* Comparison function for two elements */

要排序的陣列作為 void 指標傳遞,因此可以操作任何型別元素的陣列。接下來的兩個引數告訴 qsort() 它應該在陣列中預期有多少元素,以及每個元素的大小(以位元組為單位)。

最後一個引數是一個指向比較函式的函式指標,該函式本身帶有兩個 void 指標。通過使呼叫者提供此功能,qsort() 可以有效地對任何型別的元素進行排序。

這是比較浮點數的比較函式的一個例子。請注意,傳遞給 qsort() 的任何比較函式都需要具有此型別簽名。它的多型性方式是將 void 指標引數轉換為我們希望比較的元素型別的指標。

int compare_floats(const void *a, const void *b)
{
    float fa = *((float *)a);
    float fb = *((float *)b);
    if (fa < fb)
        return -1;
    if (fa > fb)
        return 1;
    return 0;
}

由於我們知道 qsort 將使用此函式來比較浮點數,因此我們在解除引用它們之前將 void 指標引數轉換回浮點指標。

現在,在長度為 len 的陣列 array 上使用多型函式 qsort 非常簡單:

qsort(array, len, sizeof(array[0]), compare_floats);