qsort如何支持任意类型数组排序?它如何识别数组类型?
qsort 为何能排序任意类型数组?它真的知晓元素类型吗?
qsort 之所以能处理 int、double、char 甚至自定义结构体等任意类型的数组,核心在于它完全不需要知道元素的具体类型,只做通用的内存块操作,所有和类型相关的逻辑都由调用者提供:
- 通用指针
void*接收数组首地址:void*是C语言里的通用指针,可以指向任意类型的数据,不管你的数组存的是什么,qsort只需要从这个地址开始处理连续的内存块就行。 - 元素大小参数
_SizeOfElements定位元素:你必须告诉qsort每个元素占多少字节——比如int传sizeof(int),double传sizeof(double)。qsort靠这个值计算元素的内存偏移,比如要访问第n个元素,就用_Base + n * _SizeOfElements来定位,完全不用管内存里存的是什么。 - 用户自定义的比较函数决定排序规则:这是最关键的部分。qsort本身不会比较元素大小,它会把两个待比较元素的内存地址传给你写的比较函数,由你去实现具体的比较逻辑。比如排序int数组时,你把
void*转成int*再比较数值;排序字符串时,转成char**用strcmp比较。qsort只根据比较函数返回的结果(正、负、零)来决定元素的交换顺序。
至于“它是如何知晓待排序数组的类型”——答案是它根本不知道。所有关于类型的信息,都是你通过参数传递给它的:元素大小让它知道每个内存块的尺寸,比较函数让它知道怎么判断两个块的大小关系。qsort全程只做内存块的移动、交换,完全不关心块里存的是数字、字符串还是其他数据。
举个直观的例子,排序int数组时的调用逻辑:
// 自定义int比较函数 int compare_int(const void* a, const void* b) { return *(const int*)a - *(const int*)b; } int main() { int arr[] = {3,1,4,2}; qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(int), compare_int); // qsort会把arr里的元素地址逐个传给compare_int,根据返回值排序 return 0; }
内容的提问来源于stack exchange,提问作者user97662
相关产品推荐
相关产品推荐

