如何在C中对指向char的指针数组进行qsort?
Posted
技术标签:
【中文标题】如何在C中对指向char的指针数组进行qsort?【英文标题】:How to qsort an array of pointers to char in C? 【发布时间】:2011-03-30 04:23:37 【问题描述】:假设我在 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)
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
在这个函数中的用法?我完全不明白。为什么是双指针?为什么我原来的功能不起作用?
谢谢,博达·赛多。
【问题讨论】:
data
应声明为const
。
比利,如果是const,还能排序吗?
是的。该数组可以不是const
,但该数组中包含的指针应该是const
。不允许您修改这样的编译时常量文字(这样做是未定义的行为)。为此,您需要const char *data[5]
。如果您希望数组本身也保持不变,那么您可以使用const char * const data[5]
。
【参考方案1】:
如果它有助于让您头脑清醒,那么您应该在比较器中将指针转换为的类型与您传递给 qsort
的数据指针的原始类型相同(qsort 文档调用 @987654322 @)。但是对于qsort
来说,它是通用的,它只是以void*
处理所有内容,而不管它“真正”是什么。
因此,如果您正在对一个整数数组进行排序,那么您将传入一个 int*
(转换为 void*
)。 qsort 将返回两个指向比较器的void*
指针,将其转换为int*
,并取消引用以获取实际比较的int
值。
现在将int
替换为char*
:
如果您对char*
的数组进行排序,那么您将传入char**
(转换为void*
)。 qsort 将返回两个指向比较器的void*
指针,将其转换为char**
,并取消引用以获得实际比较的char*
值。
在您的示例中,因为您使用的是数组,所以您传入的 char**
是 char*
数组“衰减”到指向其第一个元素的指针的结果。由于第一个元素是char*
,指向它的指针就是char**
。
【讨论】:
【参考方案2】:假设您的数据是 double data[5]
。
您的比较方法将接收指向元素 (double) 的指针(double*,作为 void* 传递)。 现在再次用 char* 替换 double。
【讨论】:
【参考方案3】:qsort
足以对由指针以外的其他内容组成的数组进行排序。这就是 size 参数存在的原因。它不能将数组元素直接传递给比较函数,因为它在编译时不知道它们有多大。因此它传递指针。在您的情况下,您将获得指向 char *
、char **
的指针。
【讨论】:
我不明白,抱歉。qsort
的第一个参数是 *
。我通过了**
。这意味着我实际上只通过了一个*
。但是一个*
恰好是一个char *
。看?这就是我感到困惑的原因。
@bodacydo:重要的一点是比较函数将指针指向数组的元素。由于数组的每个元素都是指向字符的指针,因此比较函数对指向字符的指针进行操作。【参考方案4】:
比较函数将指针指向要排序的数组中的对象类型。由于数组包含char *
,因此您的比较函数将指针指向char *
,即char **
。
【讨论】:
【参考方案5】:来自man qsort
:
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 **
(即指向字符的指针)。
【讨论】:
【参考方案6】:char *data[5] = "boda", "cydo", "washington", "dc", "obama" ;
是一条语句,要求编译器提供一个大小为 5 的字符指针数组。您已经将这些指针初始化为字符串字面量,但对于编译器来说,它仍然是一个由五个指针组成的数组。
当您将该数组传递给qsort
时,根据C 数组参数传递规则,指针数组衰减为指向第一个元素的指针。
因此,您必须先处理一级间接,然后才能访问包含常量的实际字符数组。
【讨论】:
【参考方案7】:@bodacydo 这里是一个程序,可以解释其他程序员试图传达的内容,但这将是在“整数”的上下文中
#include <stdio.h>
int main()
int i , j;
int *x[2] = &i, &j;
i = 10; j = 20;
printf("in main() address of i = %p, address of j = %p \r\n", &i, &j);
fun(x);
fun(x + 1);
return 0;
void fun(int **ptr)
printf("value(it would be an address) of decayed element received = %p, double dereferenced value is %d \r\n",*ptr, **ptr);
printf("the decayed value can also be printed as *(int **)ptr = %p \r\n", *(int **)ptr );
【讨论】:
【参考方案8】:也许给你一个我的代码示例更容易。我正在尝试对 TreeNode 数组进行排序,比较器的前几行如下所示:
int compareTreeNode(const void* tt1, const void* tt2)
const TreeNode *t1, *t2;
t1=*(const TreeNode**)tt1;
t2=*(const TreeNode**)tt2;
之后,您使用 t1 和 t2 进行比较。
【讨论】:
以上是关于如何在C中对指向char的指针数组进行qsort?的主要内容,如果未能解决你的问题,请参考以下文章