2012-04-27 4 views
2

gcc compile le code suivant sans erreur. Je crée une fonction de tri à bulles qui peut être utilisée avec des tableaux de n'importe quel type de données (d'où le pointeur de fonction).Problème de tri à bulles

Il trie le tableau de chaînes de caractères (arr2) sans problème, cependant, je n'arrive pas à comprendre pourquoi il ne triera pas correctement le tableau d'entiers (arr). J'ai ajouté une instruction printf dans la fonction compare_long pour voir ce qui se passe. Il ne semble pas que les entiers lui soient passés correctement. Toute aide est la bienvenue.


#include <stdio.h> 
    #include <string.h> 

    #define MAX_BUF 256 

    long arr[10] = { 3,6,1,2,3,8,4,1,7,2}; 
    char arr2[5][20] = { "Mickey Mouse", 
         "Donald Duck", 
         "Minnie Mouse", 
         "Goofy", 
         "Pluto" }; 

    void bubble(void *p, int width, int N, int(*fptr)(const void *, const void *)); 
    int compare_string(const void *m, const void *n); 
    int compare_long(const void *m, const void *n); 

    int main(void) { 
      int i; 
      puts("\nBefore Sorting:\n"); 

      for(i = 0; i < 10; i++) {    /* show the long ints */ 
        printf("%ld ",arr[i]); 
      } 
      puts("\n"); 

      for(i = 0; i < 5; i++) {    /* show the strings */ 
        printf("%s\n", arr2[i]); 
      } 

      bubble(arr, 4, 10, compare_long);  /* sort the longs */ 
      bubble(arr2, 20, 5, compare_string); /* sort the strings */ 
      puts("\n\nAfter Sorting:\n"); 

      for(i = 0; i < 10; i++) {    /* show the sorted longs */ 
        printf("%d ",arr[i]); 
      } 
      puts("\n"); 

      for(i = 0; i < 5; i++) {    /* show the sorted strings */ 
        printf("%s\n", arr2[i]); 
      } 
      return 0; 
    } 

    void bubble(void *p, int width, int N, int(*fptr)(const void *, const void *)) { 

      int i, j, k; 
      unsigned char buf[MAX_BUF]; 
      unsigned char *bp = p; 

      for(i = N - 1; i >= 0; i--) { 

        for(j = 1; j <= i; j++) {  

          k = fptr((void *)(bp + width*(j-1)), (void *)(bp + j*width)); 

          if(k > 0) { 
            memcpy(buf, bp + width*(j-1), width); 
            memcpy(bp + width*(j-1), bp + j*width , width); 
            memcpy(bp + j*width, buf, width); 
          } 
        } 
      } 
    } 

    int compare_string(const void *m, const void *n) { 
      char *m1 = (char *)m; 
      char *n1 = (char *)n; 
      return (strcmp(m1,n1)); 
    } 

    int compare_long(const void *m, const void *n) { 
      long *m1, *n1; 
      m1 = (long *)m; 
      n1 = (long *)n; 

      printf("m1 = %l and n1 = %l\n", *m1, *n1); 

      return (*m1 > *n1); 
    } 
+6

Êtes-vous sûr que votre long est de 4 octets? Il vaudrait mieux utiliser sizeof (long) au lieu de hard-coding – TJD

+0

Bon point. Je vais essayer ça. Une sec – contrapositive

+0

Le tri des bulles n'est-il pas un simple échange? Pourquoi faites-vous face à des souvenirs? – noMAD

Répondre

1

La spécification ANSI C définit la mesure où un minimum de 4 octets (32 bits), mais GCC définit longtemps que 8 octets dans votre cas. Il est spécifique à l'architecture, donc vous devez utiliser sizeof (long) ou l'un des types C99 comme uint32_t ou int32_t si vous voulez une taille spécifique.

+0

C'est ce qu'il a fait. Merci pour l'aide. – contrapositive