3 votes

Comment trier ce tableau de pointeurs sans modifier le tri du tableau d'origine ?

J'ai créé ce fichier pour résoudre une confusion que j'avais avec les pointeurs et les tableaux de pointeurs. Je comprends jusqu'au code commenté, et je suis capable de changer l'ordre des valeurs dans p_to_pointers sans changer p_to_nums. Mais j'ai du mal à le traduire en qsort.

Voici mon résultat :

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

C'est la sortie souhaitée :

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

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

4voto

Seth Robertson Points 13276

Vous triez les *p_to_pointers avec sizeof(int) alors que je crois que vous voulez trier les p_to_pointers sizeof(int *).

compare_values devrait être ajusté pour déréférencer deux fois.

Si et c'est un grand si je comprends ce que vous essayez de faire.

De plus, votre comparaison dans compare() est inutilement complexe. Vous pouvez simplement faire une simple soustraction au lieu de deux comparaisons et une soustraction.

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

Sortie :

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

1voto

andrewdski Points 2246

Le premier argument de qsort es *p_to_pointers . C'est la même chose que p_to_pointers[0] que vous avez défini comme &p_to_nums[0] . Ce qui, à son tour, est la même chose que p_to_nums . Vous appelez donc pour qsort finit par être équivalent à

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

Ainsi, vous triez p_to_nums .

Ce que vous voulez, c'est

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

Ensuite, votre compare_values doit convertir les void* a int** plutôt que int* et vous avez besoin d'un niveau supplémentaire d'indirection dans vos déréférences. La façon habituelle d'accomplir la comparaison serait quelque chose comme ceci :

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

    return **int_b - **int_a;
}

Notez qu'en C, les casts de void* ne sont pas nécessaires (bien qu'ils le soient en C++). Notez également la soustraction plus typique dans l'élément return plutôt que votre construction plutôt inhabituelle (bien que la vôtre fonctionne).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X