qsort排序二维数组

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

base-- 指向要排序的数组的第一个元素的指针。
nitems-- 由 base 指向的数组中元素的个数。
size-- 数组中每个元素的大小,以字节为单位。
compar-- 用来比较两个元素的函数,即函数指针(回调函数)

对于arry[][]初始化的数据和malloc出来的二维数组,传参的解析方式不同

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

//数组
int com1(const void *a, const void *b)
{
    int *c = (int*)a;
    int *d = (int*)b;
    return c[1] - d[1];
}
//malloc
int com(const void *a, const void *b)
{
    int *c = *(int**)a;
    int *d = *(int**)b;
    return c[0] - d[0];
}
int main()
{
    int i = 0;
    int num1[10][3];
    int **num = (int**)malloc(sizeof(int*)*10);
    for(i = 0; i < 10; i++)
    {
       num[i] = (int*)malloc(sizeof(int)*3);
       num[i][0] = i;
       num[i][1] = i+1;
       num[i][2] = i+2;
       num1[i][0] = i;
       num1[i][1] = i+1;
       num1[i][2] = i+2;
    }
    qsort(num1, 10, sizeof(num1[0]), com1);
    qsort(num, 10, sizeof(num[0]), com);
    return 0;
}

num1是二维数组,元素地址空间是连续的,sizeof(num1[0])= 3 * sizeof(int) = 12;

num是指针数组,元素地址不连续,64位系统下sizeof(num[0])=sizoef(int*)=8;

(gdb) b 30
Breakpoint 6 at 0x4006d7: file qsort.c, line 30.
(gdb) b com
Breakpoint 7 at 0x400598: file qsort.c, line 12.
(gdb) r
Starting program: /home/luogf/20210904/a.out 

Breakpoint 6, main () at qsort.c:31
31	    qsort(num1, 10, sizeof(num1[0]), com1);
(gdb) p num[0]
$4 = (int *) 0x601070
(gdb) p num[1]
$5 = (int *) 0x601090
(gdb) p num[2]
$6 = (int *) 0x6010b0
(gdb) p &num[0]
$7 = (int **) 0x601010
(gdb) p &num[1]
$8 = (int **) 0x601018
(gdb) p &num[2]
$9 = (int **) 0x601020
(gdb) c
Continuing.

Breakpoint 7, com (a=0x601010, b=0x601018) at qsort.c:12
12	    int *c = *(int**)a;

可以看到malloc出的二维数组,qsort传递的是num[i]的地址,所以在访问num[i]的子成员时要转换成int**

int com(const void *a, const void *b)
{
    int *c = *(int**)a;
    int *d = *(int**)b;
    return c[0] - d[0];
}

而初始化好的数组每个元素都是连续,只需要按照传递的&num[i]地址做偏移就可以了。

(gdb) p &num1[0]
$23 = (int (*)[3]) 0x7fffffffe4a0
(gdb) p &num1[1]
$24 = (int (*)[3]) 0x7fffffffe4ac
(gdb) p &num1[2]
$25 = (int (*)[3]) 0x7fffffffe4b8


(gdb) p &num1[0][0]
$17 = (int *) 0x7fffffffe4a0
(gdb) p &num1[0][1]
$18 = (int *) 0x7fffffffe4a4
(gdb) p &num1[0][2]
$19 = (int *) 0x7fffffffe4a8
int com1(const void *a, const void *b)
{
    int *c = (int*)a;
    int *d = (int*)b;
    return c[1] - d[1];
}

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值