[英]Proper way to do a pointer-to-string in a qsort function
假設我有一個要排序的字符串數組,例如:
{"one", "two", "three", "four"};
使用qsort
傳遞這些字符串時正確的轉換操作是什么?
int scmp(const void *p1, const void *p2) {
// string1 = ???
};
我的想法是該項目將是“指向字符串的指針”,並且由於字符串是“指向字符的指針”,這會給我一個“指向指針的字符”。 以下是正確的方法嗎?
// 1. Pointer-to String
(String) *
// 2. String = Pointer-to-char
(char*) *
// 3. What about const-ness? Doesn't qsort require the 'value' to be const?
// Also, what about string = unsigned char -- is that important here?
(const char*) *
那么, string1
的正確定義是:
int scmp(const void *p1, const void *p2) {
const char* string1 = (const char**) p1;
};
是正確的方法嗎? 您可以看到弄清楚指針聲明(或在本例中為強制轉換)是多么乏味(至少對我而言)。 有沒有更直接的方法來做到這一點 - 也就是說,如果我知道我想要一個“指向unsigned
的const
”,我可以在不到5分鍾?
qsort
提供比較 function 與兩個指向數組元素的 const 指針開始排序。 您正在對“字符串”數組進行排序,也就是說char*
數組。 char*
數組是char*[]
,指向此類數組中元素的指針是指向char*
的指針,即char**
,指向該數組中元素的 const 指針是char*const*
.
您可能最終會使用strcmp
來比較兩個字符串或類似的東西。 如果它是strcmp
本身,你最終會得到:
int scmp(void const* va, void const* vb) {
const char* a = *(char* const*)va;
const char* b = *(char* const*)vb;
return strcmp(a, b);
}
我在a
和b
中添加了不必要但無害的const
限定符,因為strcmp
不會改變它的 arguments。 除此之外,示例代碼與您在man qsort中查看示例代碼時所發現的非常相似
由於qsort()
如何使用指向元素的指針,這有點混亂,所以如果元素本身是指針,那么您需要以某種方式將void*
轉換為char*
,但還要在此過程中取消對它的引用。
下面是一個如何編寫 function 的示例:
int qs_strcmp(const void* a, const void* b) {
return strcmp(*((const char**) a), *((const char**) b));
}
還有一個測試程序來展示它是如何工作的:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void) {
char *list[] = {
"boba",
"dada",
"zapa",
"cobb",
"acdc",
"abba"
};
int list_len = sizeof(list) / sizeof(char*);
qsort(&list[0], list_len, sizeof(char*), qs_strcmp);
for (int i = 0; i < list_len; ++i) {
printf("%s\n", list[i]);
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.