简体   繁体   中英

C: qsort doesn't seem to work with unsigned long

Can anyone please tell me what is wrong with the following example? I took it from here and replaced int by unsigned long . I also changed the cmpfunc to properly handle unsigned long .

#include <stdio.h>
#include <stdlib.h>

unsigned long values[] = { 88, 56, 100, 2, 25 };

int cmpfunc (const void * a, const void * b)
{
  if(*(unsigned long*)a - *(unsigned long*)b < 0){
    return -1;
  }

  if(*(unsigned long*)a - *(unsigned long*)b > 0){
    return 1;
  }

  if(*(unsigned long*)a - *(unsigned long*)b == 0){
    return 0;
  }
}

int main()
{
   int n;

   printf("Before sorting the list is: \n");

   for( n = 0 ; n < 5; n++ ) 
   {
      printf("%lu ", values[n]);
   }

   qsort(values, 5, sizeof(unsigned long), cmpfunc);

   printf("\nAfter sorting the list is: \n");

   for( n = 0 ; n < 5; n++ ) 
   {   
      printf("%lu ", values[n]);
   }

   return(0);
}

Here is the output I got:

Before sorting the list is: 
88 56 100 2 25 
After sorting the list is: 
25 2 100 56 88 

You comparison function is incorrect. A subtraction of unsigned values can wrap the value giving an incorrect result.

The function should only compare the values:

int compare( const void* a , const void* b )
{
    const unsigned long ai = *( const unsigned long* )a;
    const unsigned long bi = *( const unsigned long* )b;

    if( ai < bi )
    {
        return -1;
    }
    else if( ai > bi )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM