2011-06-25 61 views
3

我让这个文件弄清楚了一些有关指针和指针数组的问题。我了解直到注释掉的代码,并且能够在不更改p_to_nums的情况下更改p_to_pointers中值的顺序。但是我很难将它翻译成qsort。如何在不改变原始数组排序的情况下对指针数组进行排序?

这里是我的输出:

0 p_to_nums: 7 p_to_pointers: 7 
1 p_to_nums: 4 p_to_pointers: 4 
2 p_to_nums: 4 p_to_pointers: 4 
3 p_to_nums: 2 p_to_pointers: 2 
4 p_to_nums: 1 p_to_pointers: 1 

这是所需的输出:

0 p_to_nums: 4 p_to_pointers: 7 
1 p_to_nums: 2 p_to_pointers: 4 
2 p_to_nums: 7 p_to_pointers: 4 
3 p_to_nums: 4 p_to_pointers: 2 
4 p_to_nums: 1 p_to_pointers: 1 

而且我的代码:

int compare_values (const void *a, const void *b) { 
    const int *int_a = (const int *) a; 
    const int *int_b = (const int *) b; 

    return (*int_b > *int_a) - (*int_b < *int_a); 
} 

main() { 

    int i; 
    int nums[5]; 
    int *p_to_nums; 
    int *p_to_pointers[5]; 

    nums[0] = 4; 
    nums[1] = 2; 
    nums[2] = 7; 
    nums[3] = 4; 
    nums[4] = 1; 

    p_to_nums = &nums[0]; 

    for (i=0; i< 5; i++) { 
     p_to_pointers[i] = &p_to_nums[i]; 
    } 

    //p_to_pointers[0] = &p_to_nums[2]; 
    //p_to_pointers[2] = &p_to_nums[0]; 

    qsort(*p_to_pointers, 5, sizeof(int), compare_values); 

    for (i=0; i< 5; i++) { 
     printf("%d p_to_nums: %d p_to_pointers: %u\n", i, (p_to_nums[i]), *p_to_pointers[i]); 
    } 

    return 0; 
} 
+0

你的'p_to_pointers'值不指向指针。实际上你有1个单独的指针:'p_to_nums',它用于连续指向'nums'数组的不同元素。每个'p_to_pointer'的类型是'int *'(指向int的指针);而不是'int **'(指向指针的指针) – pmg

+0

@pmg:Bzzzt。错误的答案。 'p_to_pointer'是一个指向int的指针数组,换句话说就是'int **'。 –

+0

@Seth,我的意思是**每个**'p_to_pointer',也就是说'p_to_pointer [0]'等等......除此之外,正如你所说,整个数组的类型为'int **'。我只是觉得这个名字具有误导性(因为它是!) – pmg

回答

3

要排序* p_to_pointers用的sizeof(int)的而我相信你想排序p_to_pointers sizeof(int *)。

compare_values将需要调整为取消引用两次。

如果...这是一个很大的,如果...我明白你想要做什么。

另外,您在compare()中的比较是不必要的复杂。你可以做一个简单的减法而不是两个比较和一个减法。

int compare_values (const void *a, const void *b) { 
    const int **int_a = (const int **) a; 
    const int **int_b = (const int **) b; 

    return (**int_b - **int_a); 
} 

main() { 

    int i; 
    int nums[5]; 
    int *p_to_nums; 
    int *p_to_pointers[5]; 

    nums[0] = 4; 
    nums[1] = 2; 
    nums[2] = 7; 
    nums[3] = 4; 
    nums[4] = 1; 

    p_to_nums = &nums[0]; 

    for (i=0; i< 5; i++) { 
    p_to_pointers[i] = &p_to_nums[i]; 
    printf("%d p_to_nums: %d p_to_pointers: %u\n", i, (p_to_nums[i]), *p_to_pointers[i]); 
    } 

    qsort(p_to_pointers, 5, sizeof(int *), compare_values); 

    for (i=0; i< 5; i++) { 
    printf("%d p_to_nums: %d p_to_pointers: %u\n", i, (p_to_nums[i]), *p_to_pointers[i]); 
    } 

    return 0; 
} 

输出:

0 p_to_nums: 4 p_to_pointers: 4 
1 p_to_nums: 2 p_to_pointers: 2 
2 p_to_nums: 7 p_to_pointers: 7 
3 p_to_nums: 4 p_to_pointers: 4 
4 p_to_nums: 1 p_to_pointers: 1 

0 p_to_nums: 4 p_to_pointers: 7 
1 p_to_nums: 2 p_to_pointers: 4 
2 p_to_nums: 7 p_to_pointers: 4 
3 p_to_nums: 4 p_to_pointers: 2 
4 p_to_nums: 1 p_to_pointers: 1 
+0

好的,我应该阅读你在写我的时候发布的内容,而不是完成。你的描述与我所做的完全相同,包括注意比较函数的异常返回。 +1给你,我删除了我的。 – andrewdski

+0

@andrewdski,我建议取消你的;我以为你有更好的解释。 (这不会减损塞思的解释 - 只是说你对我的态度更好:) – sarnold

+0

啊我希望你没有删除那么。 :(这个解释与我现在所处的位置相差一半,仍然试图理解它在做什么...... –

1

的第一个参数是qsort*p_to_pointers。这与您设置为&p_to_nums[0]p_to_pointers[0]相同。那反过来也就是p_to_nums。所以你打电话qsort最后等于到

qsort(p_to_nums, 5, sizeof(int), compare_values); 

因此,要排序p_to_nums

你想要的是

qsort(p_to_pointers, 5, sizeof(int*), compare_values); 

然后你compare_values有转换的void*int**而非int*,你需要间接的在你解引用一个额外的水平。完成比较常用的方法是这样的:

int compare_values (const void *a, const void *b) { 
    const int **int_a = a; 
    const int **int_b = b; 

    return **int_b - **int_a; 
} 

注意,在C从void*石膏是没有必要的(尽管在C++他们)。还请注意return声明中更典型的减法,而不是您非常不寻常的构造(尽管您的作品)。

相关问题