如何解决qsort 比较函数中的 const 限定符
我使用 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()
中进行转换。
但是我的无转换方法不是更正确吗?我收到警告,直到我将 const
放在它所属的位置。
解决方法
const
的中间中的 char *const *sp1 = vep1
表示 *sp1
指定的任何内容都是 const
。这是必需的,因为 const void *
表示指针直接指向的内存应该是 const
。
您是对的,因为 const void *
不能在没有强制转换的情况下分配给 const char **
,因为它不是 const 正确的。我个人尽量避免强制转换,因此我更喜欢您的代码而不是使用强制转换的代码。
然而,使用const char *const *sp1
会更正确一些,因为没有理由cmpstringp
不应该实际上也为const char **
工作!
重新排序和对齐后,从右到左转换的内容和保守的变得更加清晰:
int cmpstringp(void const *vep1,const void *vep2) {
char * const *sp1 = vep1,...
const
被复制,“to void”被“to pointer (to char) 替换。它甚至不必是指针(例如结构体)。如果,那么我对此表示怀疑const-ness 可以扩展到所有引用,只是因为“比较”函数根本不应该修改。它可以修改所有对象,但不能修改正在排序的对象。
这一切都很有趣,但逻辑上很复杂。就像有一排盒子,里面有字母。首先,您将每个框内的字母按照它们本身进行排序(不要触摸框),然后根据字母对框进行排序(但不要触摸它们,即字母)。
感谢您的评论和回答。
6.5.16.1 简单赋值可能会处理这种情况。
指针分配的 3 个项目符号似乎需要:
- 兼容类型,或者一种是无效的
- 左侧具有右侧的所有限定词。
- 右边的空指针没问题
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。