如何在C中对指向char的指针数组进行qsort排序?
假设我有一个指向C中char的指针数组:如何在C中对指向char的指针数组进行qsort排序?,c,sorting,qsort,double-pointer,C,Sorting,Qsort,Double Pointer,假设我有一个指向C中char的指针数组: char *data[5] = { "boda", "cydo", "washington", "dc", "obama" }; 我希望使用qsort对该数组进行排序: qsort(data, 5, sizeof(char *), compare_function); 我想不出比较函数。出于某种原因,这不起作用: int compare_function(const void *name1, const void *name2) { cons
char *data[5] = { "boda", "cydo", "washington", "dc", "obama" };
我希望使用qsort对该数组进行排序:
qsort(data, 5, sizeof(char *), compare_function);
我想不出比较函数。出于某种原因,这不起作用:
int compare_function(const void *name1, const void *name2)
{
const char *name1_ = (const char *)name1;
const char *name2_ = (const char *)name2;
return strcmp(name1_, name2_);
}
我进行了大量搜索,发现我必须在qsort内部使用**
:
int compare_function(const void *name1, const void *name2)
{
const char *name1_ = *(const char **)name1;
const char *name2_ = *(const char **)name2;
return strcmp(name1_, name2_);
}
这是有效的
有人能解释一下*(const char**)name1在这个函数中的用法吗?我一点也不明白。为什么是双指针?为什么我原来的功能不起作用
谢谢,Boda Cydo。想象你的数据是双数据[5]
您的compare方法将接收指向元素(double)的指针(double*,作为void*传递)。
现在再次将double替换为char*。qsort
足够通用,可以对由指针以外的其他内容组成的数组进行排序。这就是size参数存在的原因。它不能将数组元素直接传递给比较函数,因为它在编译时不知道它们有多大。因此,它传递指针。在您的例子中,您可以从manqsort
获得指向char*
,char**
的指针:
The contents of the array are sorted in ascending
order according to a comparison function pointed to by
compar, which is called with two arguments that **point**
to the objects being compared.
因此,听起来比较函数获取指向数组元素的指针。现在,指向char*
的指针是char**
(即指向字符指针的指针)。char*data[5]={“boda”、“cydo”、“washington”、“dc”、“obama”}代码>
是一条语句,要求编译器提供大小为5的字符指针数组。您已经将这些指针初始化为字符串文本,但对于编译器来说,它仍然是一个由五个指针组成的数组
当您将该数组传递到qsort
中时,指针数组将根据C数组参数传递规则衰减为指向第一个元素的指针
因此,在获得包含常量的实际字符数组之前,必须先处理一级间接寻址。如果这有助于保持头脑清醒,那么应该在比较器中转换指针的类型与传递到qsort
(qsort文档称之为base
)。但是对于qsort
的泛型,它只是将所有内容作为void*
处理,而不管它“真正”是什么
因此,如果要对int数组进行排序,那么将传入一个int*
(转换为void*
)。qsort将返回两个指向比较器的void*
指针,将其转换为int*
,然后取消引用以获得实际比较的int
值
现在将int
替换为char*
:
如果要对char*
数组进行排序,则将传入一个char**
(转换为void*
)。qsort将返回两个指向比较器的void*
指针,将其转换为char**
,然后取消引用以获得实际比较的char*
值
在您的示例中,因为您使用的是数组,所以传入的char**
是char*
数组“衰减”的结果指向指向其第一个元素的指针。由于第一个元素是char*
,因此指向它的指针是char**
比较函数获取指向数组中要排序的对象类型的指针。由于数组包含char*
,因此比较函数获取指向char*
,即的指针de>char**
@bodacydo这里有一个程序,可以解释其他程序员试图传达的内容,但这是在“整数”的上下文中
#包括
int main()
{
int i,j;
int*x[2]={&i,&j};
i=10;j=20;
printf(“在i=%p的main()地址中,j=%p\r\n的地址中,&i,&j);
乐趣(x);
乐趣(x+1);
返回0;
}
虚无乐趣(整数**ptr)
{
printf(“接收到的衰减元素的值(将是地址)=%p,双解引用值为%d\r\n”,*ptr,**ptr);
printf(“衰减值也可以打印为*(int**)ptr=%p\r\n”,*(int**)ptr);
}
也许我给你举个代码示例比较容易。我正在尝试对树节点数组进行排序,我的比较器的前几行如下所示:
int compareTreeNode(const void* tt1, const void* tt2) {
const TreeNode *t1, *t2;
t1=*(const TreeNode**)tt1;
t2=*(const TreeNode**)tt2;
然后,使用t1和t2进行比较。数据
应该声明为常量
。Billy,如果它是常量,它仍然可以排序吗?是的。数组可以是非常量
,但该数组中包含的指针应该是常量
。不允许这样修改编译时常量文本(这样做是未定义的行为)。要实现这一点,需要const char*data[5]
。如果希望数组本身也是常量,则需要const char*const data[5]
。对不起,我不明白。qsort
的第一个参数是一个*
。我传递了一个***
。这意味着我实际上只传递了一个*
。但是一个*
恰恰是一个字符*
。看到了吗?这就是我感到困惑的原因。@bodacydo:重要的一点是比较函数使用指向元素的指针由于数组的每个元素都是指向char的指针,所以比较函数对指向char的指针进行操作。
int compareTreeNode(const void* tt1, const void* tt2) {
const TreeNode *t1, *t2;
t1=*(const TreeNode**)tt1;
t2=*(const TreeNode**)tt2;