簡體   English   中英

編譯 K&R 示例時出現問題

[英]Problem compiling K&R example

我在編譯本書第 5.11 節中介紹的示例程序時遇到了麻煩。 我已經刪除了大部分代碼,只留下了相關的東西。

#define MAXLINES 5000
char *lineptr[MAXLINES];

void qsort1(void *lineptr[], int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);

main(int argc, char *argv[]) {
    int numeric = 1;
    /* ... */
    qsort1((void**) lineptr, 0, 100, (int (*)(void*, void*))(numeric ? numcmp : strcmp));
}

void qsort1(void *v[], int left, int right, int (*comp)(void *, void *)) {
    /* ... */
}

int numcmp(char *s1, char *s2) {
    /* ... */
}

問題是代碼無法編譯(我使用的是 Digital Mars 編譯器)。 我得到的錯誤是這樣的:

        qsort1((void**) lineptr, 0, nlines - 1, (int (*)(void*, void*))(numeric
? numcmp : strcmp));

                 ^
go.c(19) : Error: need explicit cast to convert
from: int (*C func)(char const *,char const *)
to  : int (*C func)(char *,char *)
--- errorlevel 1

盡管我正確粘貼了書中的代碼,但聲明一定有問題。 我不知道如何做出正確的改變(關於 function 指針的部分當然可以寫得更廣泛)。

編輯:我應該提到我正在閱讀本書的 ANSI 版本。

我認為錯誤來自這樣一個事實,即舊的 C 還不知道 const:我認為 strcmp 有兩個指向非 const 字符( char * )的指針(這可能是它當時編譯的原因,但不是用你的編譯器)。 然而,現在 strcmp 需要char const*const char*是一回事)。 將您的 function 原型更改為:

int numcmp(char const*, char const*);

qsort()bsearch()期望的標准 function 指針具有原型:

int comparator(const void *v1, const void *v2);

代碼中定義的qsort1()期望:

int comparator(void *v1, void *v2);

代碼中定義的比較器函數沒有那個原型,不同的function指針類型之間沒有自動轉換。

因此, qsort1()的修復是:

  1. 引入演員表: (int (*)(void *, void *)) ,或
  2. 重寫比較器:

     int numcmp(void *v1, void *v2) { char *s1 = v1; char *s2 = v2; ... } int str_cmp(void *v1, void *v2) // Note new function name, { return(strcmp(v1; v2)); }

顯然,對qsort1()的調用將引用str_cmp而不是strcmp 作者試圖避免使用中間 function,但與當今使用的(合法的)更復雜的編譯器相沖突。

qsort()的標准版本需要一堆const限定符,就像這個答案的第一個版本一樣。

這是一個常見的問題:)

以下行告訴qsort期望一個指向帶有兩個 void* 參數的 function 的指針。 不幸的是, strcmp需要兩個不可修改的字符串,因此它的簽名是

int (*comp)(const char*, const char*)

而不是你所擁有的:

int (*comp)(void *, void *)

更改qsort1numeric的簽名:

qsort1(void *v[], int left, int right, int (*comp)(const void *, const void *))

和:

int numcmp(const char*, const char*)

請注意, strcmp需要兩個const arguments,而您的numcmp不需要。 因此,這兩個函數的類型不匹配,並且? : ? :運營商會投訴。

執行以下操作之一:

  1. 更改numcmp以在 constness 方面匹配strcmp原型
  2. (int (*)(void*, void*))推入? : ? : , 例如

    numeric? (int (*)(void*, void*))numcmp: (int (*)(void*, void*))strcmp

自從我完成任何純 C 編程以來已經有一段時間了,我不確定新標准。

但是,轉換為 void ** 會創建一個指向 function 需要指向數組的指針的指針。 當然,它們在內部是相同的,但是強類型檢查會將其視為錯誤。

重寫 qsort 以接受 ** 而不是 *[] ,你應該沒問題。

暫無
暫無

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

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