首先,我定义了一个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));
然后我尝试在它上面使用qsort()
。
qsort( array, number, sizeof array[0], compare );
这是我的比较函数。它按第一列的整数值排序,然后按第二列排序,同时保留第一列的顺序。例如,"02,17,01"将变为"01,02,17"。
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;
}
- 问题**
这对静态数组有效,我知道现在不行了,因为我有一个动态数组,它是一个指针数组。
如何修改这段代码以使用动态创建的多维数组?
7条答案
按热度按时间xt0899hw1#
样本码
什么一个月
数组= {(整数 *),(整数 *),(整数 *),...,(整数 *)}
qsort需要每个元素的地址(对于交换等,因为元素的大小和个数以及起始地址自只给出信息)。
例如&(整数 *),&(整数 *)
因此
(int **)
传递给函数compare。调用
compare(int **, int **)
&(int*)
表示参数int**
比较函数原型是
cmp(const void*, const void*)
将转换
(const int**)pa
转换为传递的原始指针。*((const int **)pa)
是取消引用的原始元素指针(int*
)uqcuzwp82#
既然你现在有了一个指针数组,那么你的比较函数的参数就是指向指针的指针。
现在你有了
a
和b
作为两个指针指向你要排序的数组,每一个指针指向排序函数要求你检查的一个元素,你可以用*a
和*b
或者a[0]
和b[0]
来访问这些元素,但是不能用a[1]
或者b[1]
。如果sort函数要求比较数组中的第一个元素(*a
)和第五个元素(*b
),那么a[1]
和b[1]
就是数组中的第二个和第六个元素--这与您要进行的比较完全无关。在第一级解引用之后,你可以做任何你需要做的事情来检查被比较的元素,因为你的数组元素本身就是指向数组的指针(每个2 x 1 m 12 n 1 x),
int
可以作为a[0][0]
a[0][1]
b[0][0]
b[0][1]
进行访问。请注意,这与a[1][0]
和b[1][0]
的顺序相反。将它们写成
(*a)[0]
会提醒我们第一级间接寻址是一个“单元素访问”指针,我不确定这是否会使整个事情变得更清楚。jc3wubiy3#
我遇到了这个线程在寻找我的一个同上的问题,我最后结束了做下面的事情。
在我上面的代码中,我直接使用了qsort API,你可以在一个连续的内存上使用这个API或者其他排序算法,但是如果你有一个矩阵,它的行是指向它的列的内存的指针呢(就像在我的情况下,以及在这个线程的问题中描述的)。因此,我复制这样的矩阵到一个连续的内存中,对该连续存储器运行排序,并将排序后的元素复制回矩阵。
上面的解决方案对我很有效,我想它可能对其他人有帮助,所以我发布了它,建议任何改进相同的。
wfypjpf44#
@BLUEPIXY,这个不对,刚好
因为pa是const void *(数组[0]),它很好地转换为const int *
mbyulnm05#
@BLUEPIXY,这个不对,刚好
lf5gs5x26#
mwngjboj7#
对于此静态数组,数组[0]的大小将为“2 * sizeof(int)"。
对于此指针到指针,数组[0]的大小将为“大小(int*)"。对于此指针到指针,数组[0][0]的大小将为“大小(int)"。
所以,首先你不能使用“qsort(数组,数字,数组[0]的大小,比较);“在指针到指针实现的情况下。