qsort 函数的使用——对普通数组、指针数组、二维数组中的元素进行排序

在ANSI C中,qsort函数的原型是

#include <stdlib.h>

void qsort(void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *));

解释:qsort函数对含有nmemb个元素的数组进行排序,而base指针指向数组的第一个元素。这个数组的元素个数由size指定。

compar函数对qsort的比较操作进行定义,所以可以定制数字的比较,字符串的比较,甚至结构体的比较,等等。compar的写法见下面几个例子。

 

一、使用qsort函数对普通数组进行排序。

代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int compare(const void *arg1, const void *arg2);
 5 
 6 int 
 7 main(int argc, char** argv)
 8 {
 9     int i;
10     
11     int arr[5] = { 13, 17, 2, 7, 71 };
12     
13     qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(int), compare);
14     
15     for (i = 0; i < 5; i++) {
16         printf("%d ", arr[i]);
17     }
18     printf("\n");
19 }
20 
21 
22 int compare(const void *arg1, const void *arg2) {
23     int a = *(int*)arg1;
24     int b = *(int*)arg2;
25     if (a > b) {
26         return 1;
27     }
28     else if (a < b) {
29         return -1;
30     }
31     else {
32         return 0;
33     }
34 }

讲一下参数compar的定义,由于qsort要求传入一个函数指针,所以这个函数的名字我们可以自己设置,就跟其他形参的名字一样,一般用cmp或者compare。

qsort函数把我们传入的arr当做指向数组第一个元素的指针,所以相应地,在代码第22行,形参表中的arg1和arg2,就是指向数组某个元素的指针

在第23行和第24行,我们将void*转换为int*,并且将指针解引用之后的值赋予a和b,进行比较。

如果a>b返回1,a<b返回-1,就意味着我们进行元素的升序排序,将元素从小到大进行排序。

 

二、使用qsort函数对指针数组进行排序。

代码如下:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 int compare(const void *arg1, const void *arg2);
 6 
 7 int 
 8 main(int argc, char** argv)
 9 {
10     int i;
11     
12     char *arr[5] = { "i", "love", "c", "programming", "language" };
13     
14     qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(char *), compare);
15     
16     for (i = 0; i < 5; i++) {
17         printf("%s ", arr[i]);
18     }
19     printf("\n");
20     /* getchar(); */
21 }
22 
23 int compare(const void *arg1, const void *arg2) {
24     char *a = *(char**)arg1;
25     char *b = *(char**)arg2;
26     int result = strcmp(a, b);
27     if (result > 0) {
28         return 1;
29     }
30     else if (result < 0) {
31         return -1;
32     }
33     else {
34         return 0;
35     }
36 }

 

与平常我们所用的数组相比,指针数组有些难理解,其实第12行的arr数组,它就是存放着5个指针,第1个元素存放指向常量字符串"i"的地址,第2个元素存放指向常量字符串"love"的地址,依此类推。

那么我们向qsort传入arr之后,qsort将arr理解为指向数组中第一个元素的指针,所以第23行形参表中,arg1和arg2其实是指向指向常量字符串的指针的指针,是char**。而我们需要传给strcmp这个字符串比较函数的,是“指向字符串的指针”,是char*,所以我们将void*转换为char**,然后解引用,得到char*,赋予a和b。接下来使用strcmp对a和b进行比较。

 

三、使用qsort函数对指针数组进行排序。

代码如下:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 int compare(const void *arg1, const void *arg2);
 6 
 7 int 
 8 main(int argc, char** argv)
 9 {
10     int i;
11     
12     char arr[5][16] = { "i", "love", "c", "programming", "language" };
13     
14     qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), compare);
15     printf("%s\n", arr[0]);
16     for (i = 0; i < 5; i++) {
17         printf("%s ", arr[i]);
18     }
19     printf("\n");
20     /* getchar(); */
21 }
22 
23 int compare(const void *arg1, const void *arg2) {
24     char *a = (char*)arg1;
25     char *b = (char*)arg2;
26     int result = strcmp(a, b);
27     if (result > 0) {
28         return 1;
29     }
30     else if (result < 0) {
31         return -1;
32     }
33     else {
34         return 0;
35     }
36 }

 

二维数组比较常见,但是在qsort函数中要对这个数组中的元素进行排序,理解起来稍微有些难度。不过一步一步分析,思路也就自然了。

这里对二维数组进行排序,其实是对二维数组的第二维中存放的字符串进行排序。所以在第14行对qsort函数的调用中,第二个参数是待排元素的个数(5个),第三个参数是待排元素的大小(16)。

我们将arr传入qsort函数,qsort函数将arr理解为指向数组第一个元素的指针,arr的第一个元素是arr[0][0],所以参数arg1和arg2指的是指向"a[i][0]"的指针,我们知道,a[i][0]是字符,就是char,所以arg1和arg2指的是char *。我们将void*转换为char*,赋予a和b,调用strcmp函数对a和b进行比较。

 

就是这样。

转载于:https://www.cnblogs.com/nipan/p/4119714.html

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
qsort函数可以用来对二维数组进行排序。在调用qsort函数时,需要传入数组的首地址、比较元素的个数、每个元素相关拷贝空间的大小和比较函数函数指针。例如,对于一个二维数组b_arr,可以使用qsort函数进行排序,如下所示:qsort(b_arr, 3, 3 * sizeof(int), cmp2)。 举例来说,如果有以下二维数组: {{1,1,0}, {3,0,2}, {1,1,1}, {1,2,0}} 通过调用qsort函数后,数组会被排序为: {{1,1,0}, {1,1,1}, {1,2,0}, {3,0,2}} 如果只想对二维数组的第一行进行排序,可以修改比较函数cmp2,使其比较当前传入的二维数组所对应的值。同时,在调用qsort函数时,需要传入第一行第一列的首地址,只比较三个元素,而元素相关空间只有1个int大小。具体示例如下: cmp2的比较方式为:((int *)a) - ((int *)b) qsort的调用方式为:qsort(&(b_arr), 3, 1 * sizeof(int), cmp2)<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [C学习:qsort快排函数在二维数组的灵活应用](https://blog.csdn.net/qq_17256689/article/details/108937155)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [二维数组排序](https://download.csdn.net/download/e970316/5172573)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值