[英]Sorting structure with C qsort()
難以理解實現C內置的qsort()來按存儲的int值(hitCount)對結構數組進行排序的情況。
我的結構:
typedef struct words {
const char *word;
int hitCount;
} words;
我正在嘗試使用Microsoft( http://support.microsoft.com/kb/73853 )給出的示例。
因此,我名列前茅:
typedef int (*compfn)(const void*, const void*);
和比較方法:
int compare (words *a, words *b) {
if (a->hitCount > b->hitCount) {
return -1;
} else if (a->hitCount < b->hitCount) {
return 1;
} else {
return 0;
}
}
然后在另一個方法中,我使用數組名稱和其他詳細信息調用qsort替換了Microsoft的示例:
qsort((void *) &output, outputLength, sizeof(words), (compfn)compare);
這給出了分段錯誤。
我不完全了解如何使用qsort,因此我假設我從Microsoft的示例改編了它,但是我做錯了。
我希望我已經包含了錯誤,並且可以對我應該做些什么有所啟發以使它正確地工作。
非常感謝!
您必須將數組而不是數組的地址傳遞給qsort。
qsort( output, ... );
同樣,您的compare函數必須返回一個int並接受兩個const void *參數。 將您的函數int compare (words *a, words *b)
強制轉換為其他類型(但正確),然后由qsort()調用將導致不確定的行為。
比較函數必須為:
int compare (const void *a, const void *b)...
然后,將a和b強制轉換為正確的類型:
((words*)a)->hitCount < ((words*)b)->hitCount
我懷疑outputLength計算不正確。 一個完整的工作示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct words {
const char *word;
int hitCount;
} words;
int compare(const void * left, const void * right) {
const words * a = (const words *) left;
const words * b = (const words *) right;
if (a->hitCount > b->hitCount) {
return -1;
} else if (a->hitCount < b->hitCount) {
return 1;
} else {
return 0;
}
}
int main() {
struct words output[] = {
{ "hello", 314 },
{ "world", 42 },
{ "answer", 42 }
};
int outputLength = sizeof(output) / sizeof(output[0]);
int i;
output[0].word = "hello";
output[0].hitCount = 314;
output[1].word = "world";
output[1].hitCount = 42;
qsort(output, outputLength, sizeof(words), compare);
for (i = 0; i < outputLength; ++i) {
printf("%d %s\n", output[i].hitCount, output[i].word);
}
return 0;
}
標准庫函數qsort
的原型是
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
注意compare
功能的簽名。 您不能將指針轉換為具有不同簽名的函數並使它正常工作。 因此,類型轉換您的比較功能將不起作用。 它必須具有與qsort
原型中聲明的簽名相同的簽名。 將compare
功能更改為-
int compare(const void *a, const void *b) {
int c = ((words *) a)->hitCount;
int d = ((words *) b)->hitCount;
if(c > d) return -1;
if(c < d) return 1;
return 0;
}
qsort
的第一個參數base
址是包含要排序元素的緩沖區的基址。 此外,任何指針類型都可以與void *
變量賦值兼容,因此您無需強制轉換基地址。 因此,您應該將qsort
函數稱為-
qsort(output, outputLength, sizeof output[0], compare);
可以使用:
int compare (const void *a, const void *b) {
if (((words *)a)->hitCount > ((words *)b)->hitCount) {
return -1;
} else if (((words *)a)->hitCount < ((words *)b)->hitCount) {
return 1;
} else {
return 0;
}
}
並致電進行排序:
qsort(output, outputLength, sizeof(words), compare);
多虧了大家的幫助,但大多數還是歸功於“自我”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.