2

qsort在这里工作,但如果数组的每个成员都v占用sizeof(void *),为什么qsort期待sizeof(int)

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

int comp(const void *pa, const void *pb)
{
    int a = *(int *)pa;
    int b = *(int *)pb;

    if (a > b)
        return +1;
    else
    if (b > a)
        return -1;
    else
        return 0;
}

int main(void)
{
    int i, a[] = {3, 1, 2, 0, 4};
    void **v;

    v = malloc(sizeof(void *) * 5);
    for (i = 0; i < 5; i++) {
        v[i] = &a[i];
    }
    for (i = 0; i < 5; i++) {
        printf("%d\n", *(int *)v[i]);
    }
    qsort(v[0], 5, sizeof(int), comp); // why sizeof(int) if v is void **
    printf("Sorted:\n");
    for (i = 0; i < 5; i++) {
        printf("%d\n", *(int *)v[i]);
    }
    free(v);
    return 0;
}
4

1 回答 1

6
qsort(v[0], 5, sizeof(int), comp); // why sizeof(int) if v is void **

您传递给的要排序的内存块的起始地址qsort

v[0] = &a[0]

的初始元素的地址a,因此您排序的数组是a,而不是初始元素v指向的块。a的元素是ints,所以sizeof(int)是正确的大小。

如果要对指针数组进行排序,则需要将该数组中第一个元素的地址传递给&v[0],或者简单地v传递给qsort。那么当然 size 参数必须是sizeof (void*)

qsort(v, 5, sizeof(void*), cmp);

但为此,您不能使用您拥有的比较功能,您需要

int cmp(const void *pa, const void *pb) {
    int a = *(int*)(*(void**)pa);
    int b = *(int*)(*(void**)pb);

    if (a > b)
        return +1;
    else
    if (b > a)
        return -1;
    else
        return 0;
}

或类似的东西。由于传递给比较函数的qsort是要比较的东西的地址,我们需要一个间接来获取要比较的指针,因为这里我们想通过指针指向的int值来比较指针,所以我们需要第二个间接来得到指向的ints。

于 2013-07-10T12:03:20.603 回答