qsort如何能够接受任何数组类型并对其进行排序?

How is qsort able to take in any array types and sort it?

提问人:user97662 提问时间:9/17/2022 最后编辑:Vlad from Moscowuser97662 更新时间:9/17/2022 访问量:42

问:

qsort具有以下功能protype

void qsort(
    void*  _Base,
    size_t _NumOfElements,
    size_t _SizeOfElements,
    _CompareFunction
    );

它怎么可能对任何数组类型(int、double、char 等)进行排序? qsort 如何知道我要求它排序的数组类型?

数组 C 函数 比较 qsort

评论

1赞 G.M. 9/17/2022
文档中的示例应该可以回答您的问题。
1赞 Weather Vane 9/17/2022
它不知道类型。参数定义了抽象数组,并且至关重要地定义了一个进行比较的函数:您自己的函数,其中应用了知识。回调函数。
0赞 ggorlen 9/17/2022
qsort不需要知道类型,只需要知道尺寸。您在参数 3 中告诉它,它用于确定哪些内存位置绑定了每个元素以传递给比较器。您的比较器将完成剩下的工作,将其转换为正确的类型。void *

答:

2赞 Vlad from Moscow 9/17/2022 #1

这是由于比较函数在比较数组的元素时将 void 指针转换为所需的类型。

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>

int cmp( const void *px, const void *py )
{
    int x = *( const int * )px;
    int y = *( const int * )py;

    return ( y < x ) - ( x < y );
}

int main( void ) 
{

    int a[] ={5, 3, 1, 9, 8, 2, 4, 7};
    const size_t N = sizeof( a ) / sizeof( *a );

    for (size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );

    qsort( a, N, sizeof( *a ), cmp );
    
    for (size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

程序输出为

5 3 1 9 8 2 4 7 
1 2 3 4 5 7 8 9 

正如您在比较函数中看到的那样,传递的指针被强制转换为所需的类型。cmp

int x = *( const int * )px;
int y = *( const int * )py;

若要遍历数组,该函数按以下方式使用指针算术。最初,指针指向传递的数组的第一个元素。例如,为了移动指向数组的第 i 个元素的指针,它执行如下操作qsort_Base

void *ith_element_ptr = ( char * )_Base + i * _SizeOfElements;

评论

0赞 Weather Vane 9/17/2022
是的,因为你用用户定义的函数来判断哪个进行比较,因为你是唯一一个知道你传递的数组中每个元素的结构,以及以什么顺序排序的人。在某些情况下,它将是一个数组,您可以考虑多个成员:如果主要成员相等,则比较其他成员。在整数数组的简单情况下,此函数将控制如何按升序或降序排序。qsortstruct