簡體   English   中英

qsort-C標准庫 - 如何使用非const args發送比較函數?

[英]qsort-C standard library-how to send a compare function with non const args?

我正在做一個家庭作業項目。 我需要實現一個符合員工創建的標題的通用列表。 他們在標題中定義了比較函數,如下所示:

typedef int(*CompareListElements)(ListElement, ListElement);

(ListElement =無效*)

我試圖使用標准庫中的qsort,但我無法編譯程序,因為我試圖傳遞給qsort的compare函數獲得非const參數。 有沒有辦法傳遞它? 謝謝你。

我試圖實現的功能:

ListResult listSort(List list, CompareListElements compareElement) {
    CHECK_RETURN(((list == NULL)||(compareElement == NULL)),LIST_NULL_ARGUMENT);
    int size=0;
    ListElement* elementArray=listToArray(list, &size);
    CHECK_RETURN((elementArray == NULL), LIST_OUT_OF_MEMORY);
    qsort(elementArray, size, sizeof(*elementArray), compareElement);
    returnArrayToList(list,elementArray);
    return LIST_SUCCESS;
}

錯誤:從不兼容的指針類型傳遞'qsort'的參數4

比較函數我試圖使用標准庫中的qsort

不好,試着避免這個:

只需將compare函數包裝到編譯器接受的另一個函數中,然后傳遞給qsort()

在包裝內,你可以使用Casting-Hammer來裝配東西...... ;-)

#include <stdlib.h>

typedef void* ListElement;
typedef int(*CompareListElements)(ListElement, ListElement);

CompareListElements c =  ... /* Initialise properly here. */

int cmp(const void * pv1, const void * pv2)
{
  return c((ListElement)pv1, (ListElement)pv2); /* Hammering here ... */
}


int main(void)  
{
  int a[4] = {3, 0, 2, 1};
  qsort(a, sizeof *a, 4, cmp);
}

參考你的編輯提供listSort()的實現,你仍然可以使用我在上面提出的解決方法,使用GNU擴展函數qsort_r()

int cmp_r(const void * pv1, const void * pv2, void * pv)
{
  CompareListElements c_r = pv;
  return c_r((ListElement)pv1, (ListElement)pv2); /* Still hammering here ... */
}

ListResult listSort(List list, CompareListElements compareElement) 
{
  ...

  qsort_r(elementArray, size, sizeof(*elementArray), cmp_r, compareElement);

  ...
}

此示例顯示如何使用為qsort提供的compare()的參數。 它將const void*指針強制轉換為您要比較的類型。 請注意,我本可以返回兩個數字之間的簡單差異,但在某些情況下,當差異“包裝”時,可能會導致未定義的行為。

你對你的鏈表很少說,所以我堅持問題標題,關於qsort() 它需要const指針的原因是為了防止你的compare()函數直接改變數據:它根據讀取數據值返回一個值。 顯然數據本身不能是const否則qsort()將無法操縱它。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ARRSIZE  10

struct numarr {
    int numb;
    struct numarr *next;
    };

struct numarr array [ARRSIZE];

int compare( const void *arg1, const void *arg2 )
{
    if (((struct numarr*)arg1)->numb > ((struct numarr*)arg2)->numb)
        return 1;
    if (((struct numarr*)arg1)->numb < ((struct numarr*)arg2)->numb)
        return -1;
    return 0;
}    

int main() {
    int i;
    srand((unsigned)time(NULL));

    // set up a random array
    printf ("Unsorted: ");
    for(i=0; i<ARRSIZE; i++){
        array[i].numb = rand() % ARRSIZE;
        printf ("%d ", array[i].numb);
    }
    printf ("%\n");

    // sort and print the array
    qsort (array, ARRSIZE, sizeof(struct numarr), compare);
    printf ("Sorted:   ");
    for(i=0; i<ARRSIZE; i++){
        printf ("%d ", array[i].numb);
    }
    printf ("%\n");
    return 0;
}

程序輸出

Unsorted: 8 7 3 0 7 5 9 2 0 0
Sorted:   0 0 0 2 3 5 7 7 8 9

暫無
暫無

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

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