2011-06-25 107 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聲明中更典型的減法,而不是您非常不尋常的構造(儘管您的作品)。

相關問題