[英]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()
的修復是:
(int (*)(void *, void *))
,或重寫比較器:
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 *)
更改qsort1
和numeric
的簽名:
qsort1(void *v[], int left, int right, int (*comp)(const void *, const void *))
和:
int numcmp(const char*, const char*)
請注意, strcmp
需要兩個const arguments,而您的numcmp
不需要。 因此,這兩個函數的類型不匹配,並且? :
? :
運營商會投訴。
執行以下操作之一:
numcmp
以在 constness 方面匹配strcmp
原型將(int (*)(void*, void*))
推入? :
? :
, 例如
numeric? (int (*)(void*, void*))numcmp: (int (*)(void*, void*))strcmp
自從我完成任何純 C 編程以來已經有一段時間了,我不確定新標准。
但是,轉換為 void ** 會創建一個指向 function 需要指向數組的指針的指針。 當然,它們在內部是相同的,但是強類型檢查會將其視為錯誤。
重寫 qsort 以接受 ** 而不是 *[] ,你應該沒問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.