我可以使用 qsort 以两种方式对字符串数组(argv
本身)进行排序。我从 linux man 3 qsort
示例开始。 cmpstringp
只有一行:
/* The actual arguments to this function are "pointers to
pointers to char", but strcmp(3) arguments are "pointers
to char", hence the following cast plus dereference */
return strcmp(*(const char **) p1, *(const char **) p2);
我尝试重新编写它,它仅在没有警告的情况下编译
char *const* sp1 = vep1
即const
位于中间 - 它是 argv
条目(?)。至少这是 qsort 声明所要求的。上面的手册页转换似乎不同且复杂。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* vep: void pointer to elements being qsorted
sp: string pointer (char **) */
int
cmpstringp(const void *vep1, const void *vep2) {
char *const *sp1 = vep1,
*const *sp2 = vep2;
return strcmp(*sp1, *sp2);
}
/* Make char* from void*, and even char */
int
cmpchar(const void *p1, const void *p2) {
const char *cp1 = p1,
*cp2 = p2;
char c1 = *cp1,
c2 = *cp2;
if (c1 == c2)
return 0;
else
return c1 > c2 ? 1 : -1;
}
/* Sort cmd line args in two ways with qsort */
int main(int argc, char **argv) {
/* sort chars of each string */
for (int i = 1; i < argc; i++)
qsort(argv[i], // base / first
strlen(argv[i]), 1, // n_elems, elem_size
cmpchar);
/* sort argv strings 1 to argc-1 */
qsort(argv + 1,
argc - 1, sizeof *argv,
cmpstringp);
for (int j = 1; j < argc; j++)
puts(argv[j]);
return 0;
}
第二个 cmp 函数 cmpchar
有一个额外的赋值级别。如果没有的话,就会有一些无害的星星,例如 if (*cp1 == *cp2)
。
How do I sort the elements of argv in C?有一个类似于手册页的解决方案,直接在 strcmp()
中进行强制转换。
但是我的无 Actor 方法不是更正确吗?在我将 const
放在它所属的位置之前,我收到了警告。
最佳答案
const
在 char *const *sp1 = vep1
的中间表示 *sp1
指定的任何内容是 const
。这是必需的,因为 const void *
表示指针直接指向的内存应该是 const
.
你说得对const void *
不可分配给const char **
没有强制转换,因为它不是 const 正确的。我个人尝试尽可能避免强制转换,因此更喜欢您的代码而不是使用强制转换的代码。
但是,使用 const char *const *sp1
会更正确一些。 ,因为没有理由cmpstringp
实际上不应该为 const char **
工作也是!
关于qsort 比较函数中的 const 限定符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67526854/