[英]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.