C qsort()具有动态n乘2多维数组

Leg*_*dre 5 c qsort dynamic-arrays

首先,我定义了一个包含2列和10行的动态数组.number例如,这里整数设置为10.

int** array;
int number = 10;

array = malloc(number * sizeof(int*));

for (i = 0; i < number; i++)
    array[i] = malloc(2 * sizeof(int));
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用qsort()它.

qsort( array, number, sizeof array[0], compare );
Run Code Online (Sandbox Code Playgroud)

这是我的比较功能.它按第一列中的整数值排序,然后按第二列排序,同时保留第一列中的顺序.例如,"0 2,1 7,0 1"将变为"0 1,0 2,1 7".

int compare ( const void *pa, const void *pb ) {
    int (*a)[1] = pa;
    int (*b)[1] = pb;
    if ( (a[0][0] < b[0][0]) || (a[0][0] == b[0][0])&&(a[1][0] < b[1][0]) ) return -1;
    if ( (a[0][0] > b[0][0]) || (a[0][0] == b[0][0])&&(a[1][0] > b[1][0]) ) return +1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这适用于静态数组.我知道它现在不起作用,因为我有一个动态数组,这是一个指针数组.

如何调整此代码以使用动态创建的多维数组?

BLU*_*IXY 13

示例代码

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

int compare ( const void *pa, const void *pb ) {
    const int *a = *(const int **)pa;
    const int *b = *(const int **)pb;
    if(a[0] == b[0])
        return a[1] - b[1];
    else
        return a[0] - b[0];
}
/*
#define NUMCMP(x,y) (((x) < (y)) ? -1 : ((x) > (y)) ? 1 : 0)

int compare ( const void *pa, const void *pb ) {
    const int (*a)[2] = *(const int (**)[2])pa;
    const int (*b)[2] = *(const int (**)[2])pb;
    int tmp;
    if((tmp=NUMCMP((*a)[0], (*b)[0]))==0)
        return NUMCMP((*a)[1], (*b)[1]);
    else
        return tmp;
}
*/    
int main(void){
    int **array;
    int number = 10;
    int i;

    array = malloc(number * sizeof(int*));
    for (i = 0; i < number; i++){
        array[i] = malloc(2 * sizeof(int));
        array[i][0] = rand()%20;
        array[i][1] = rand()%20;
    }
    for(i = 0;i < number;++i)
        printf("%2d, %2d\n", array[i][0], array[i][1]);

    printf("\n");

    qsort(array, number, sizeof array[0], compare);

    for(i = 0;i < number;++i)
        printf("%2d, %2d\n", array[i][0], array[i][1]);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

什么 *(const int **)pa

array = {(int*),(int*),(int*),...,(int*)}

qsort需要元素的每个元素地址(用于交换等等.因为元素的大小和数量以及起始地址,因为只有给定的信息).

例如&(int*),&(int*)

所以(int **)通过功能比较.

电话compare(int **, int **) &(int*)意味着在argint**

比较函数原型 cmp(const void*, const void*)

强制转换(const int**)pa为传递原始指针.

*((const int **)pa)是取消引用原始元素指针(int*)

  • 注意`return a [1] - b [1];`(和类似的表达式)是危险的,如果`a`中的值大而且正,而'b`中的值大而负(反之亦然).您可以获得算术溢出,这会导致未定义的行为.对于大多数合理的数据集,这不会是一个问题.但是,您应该知道这个问题. (3认同)