如何在不更改原始数组的排序的情况下对此指针数组进行排序?

时间:2011-06-25 23:26:26

标签: c

我制作了这个文件来解决我对指针和指针数组的困惑。我理解了直到注释掉的代码,并且能够在不改变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;
}

2 个答案:

答案 0 :(得分:3)

您正在使用sizeof(int)对* p_to_pointers进行排序,而我相信您要对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

答案 1 :(得分:1)

qsort的第一个参数是*p_to_pointers。这与您设置为p_to_pointers[0]的{​​{1}}相同。这反过来与&p_to_nums[0]相同。因此,您致电p_to_nums最终等同于

qsort

因此,您正在排序qsort(p_to_nums, 5, sizeof(int), compare_values);

你想要的是

p_to_nums

然后您的compare_values必须将qsort(p_to_pointers, 5, sizeof(int*), compare_values); 转换为void*而不是int**,并且在您的引用中需要额外的间接级别。完成比较的通常方法是这样的:

int*

请注意,在C中,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*语句中更典型的减法,而不是你不太常见的构造(虽然你的工作)。