对 Qsort 和指针感到困惑 [英] Confused about Qsort and Pointers

查看:55
本文介绍了对 Qsort 和指针感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 C 语言初学者,希望习惯术语和指针.在寻找对数值数组元素进行排序的方法时,我发现了以下工作函数原型.该函数是 qsort,它使用指针.现在我明白的是,const"这个词确保值 a 和 b 不变,但指针不变.如果我在这里错了,请纠正我.我的问题是:

I am a beginner programmer in C who wants to get used to terminology and pointers. I have found the following working function prototype while searching for a way to sort the elements of a numerical array. The function was qsort and it utilized pointers. Now what I understood is that the word "const" ensures that the values a and b are unchanged but not the pointers. Correct me if I am wrong here. My questions are:

  1. 为什么要使用void * 的函数不能使用int * 从开始?
  2. 返回部分如何构造*(int*)a工作?
  3. 为什么 qsort 算法需要这么多参数?

  1. Why do we use void * the function can we not use int * from the start?
  2. How does the construction *(int*)a in the return part work?
  3. Why does the qsort algorithm needs this many arguments?

int compare (const void *a, const void *b)
{
     return ( *(int*)a - *(int*)b ); 
}

非常感谢您的回答.PS:这对我来说是一项相当复杂的任务.

Many thanks for the answers. PS: That is a pretty complicated task for me.

推荐答案

  1. qsort 是这样制作的,因此它可以用作通用排序器.如果它从一开始就使用 int ,它只能用于比较整数.通过这种方式,您还可以通过将 strcmp 作为比较函数传递给 qsort 来对字符串进行排序.
  2. *(int*)aa 转换为指向 int 的指针,然后取消引用它,这样您就可以存储整数在 a.请注意,这不会更改 aa 指向的值.
  3. qsort 需要 4 个参数:要排序的数组,该数组中元素的数量和元素的大小,最后是比较函数.它需要所有这些信息,因为同样,它要尽可能通用.

  1. qsort was made this way so it could be used as a generic sorter. If it would use int from the start it could only be used to compare integers. This way you could also, for example, sort strings by passing strcmp as the compare function to qsort.
  2. *(int*)a casts a to a pointer-to-int and then dereferences it, so you get the integer stored at a. Note that this doesn't change a or the value that a points to.
  3. qsort requires 4 arguments: the array to sort, the number of elements in that array and the size of the elements and finally the compare function. It needs all this information, because again, it is made to be as generic as possible.

它需要元素的数量,因为在 C 中,指针不携带有关它们后面的缓冲区大小的信息.它需要知道每个元素的大小,以便将元素正确地传递给比较函数.例如,要比较 int ,您可以将 sizeof(int) 作为 size 参数传递.要比较字符串,您可以使用 sizeof(char *).

It needs the number of elements because in C pointers don't carry information about the size of the buffer that follows them. And it needs to know the size of each element so it can pass the elements to the compare function correctly. For examle, to compare ints you would pass sizeof(int) as the size parameter. To compare strings you would use sizeof(char *).

ADDIT 如 H2CO3 所建议的,使用 const void * 的原因是为了表明比较函数可能不会改变 ab.这当然是为了确保对数组进行排序不会突然改变数组中的值.而且,正如 H2CO3 所说,转换为 (const int *) 会更干净,这样您就不会在转换后意外更改值:

ADDIT as suggested by H2CO3 the reason for using const void * is to indicate that the compare function may not change the value pointed to by a and b. This, of course, to ensure that sorting the array doesn't suddenly change the values in the array. And, as H2CO3 said, it would be cleaner to cast to (const int *) so that you cannot accidentally change the value after casting it:

return *(const int *)a - *(const int *)b;

您还可以通过以下方式摆脱演员阵容:

You could also get rid of the cast with:

int compare(const void * a, const void * b){
    const int * ia = a;
    const int * ib = b;

    return *ia - *ib;
}

取决于您对演员表的喜好.(我宁愿避免它们)

depending on your tastes regarding casts. (I prefer to avoid them)

最后,澄清星号:

*(int *)a
^     ^
|     └ cast to integer pointer
└ dereference (integer) pointer

这篇关于对 Qsort 和指针感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆