开发者

How do I sort this array of pointers without changing the sort of the original array?

I made this file to work out some confusion I had with pointers and arrays of pointers. I understand up until the commented out code, and am able to change the order of the values in p_to_pointers without changing p_to_nums. But I'm having trouble translating it to qsort.

Here is my output:

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

This is the desired output:

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

And my code:

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;
}


You are sorting *p_to_pointers with sizeof(int) whereas I believe you want to sort p_to_pointers sizeof(int *).

compare_values would need to be adjusted to dereference twice.

If…and this is a big if…I understand what you are trying to do.

Also, your comparison in compare() is needlessly complex. You can just do a simple subtraction instead of two comparisons and a subtraction.

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;
}

Output:

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


The first argument to qsort is *p_to_pointers. That is the same as p_to_pointers[0] which you have set to &p_to_nums[0]. That, in turn is the same as p_to_nums. So you call to qsort ends up being equivalent to

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

Thus, you are sorting p_to_nums.

What you want is

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

Then your compare_values has to convert the void* to int** rather than int*, and you need an extra level of indirection in your dereferences. The usual way to accomplish the comparison would be something like this:

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

    return **int_b - **int_a;
}

Note that in C the casts from void* are not necessary (though in C++ they are). Also note the more typical subtraction in the return statement, rather than your rather unusual construct (though yours works).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜