2016-04-17 9 views
1

Может кто-нибудь, пожалуйста, скажите мне, что не так со следующим примером? Я взял его с here и заменил int на unsigned long. Я также изменил cmpfunc, чтобы правильно обрабатывать unsigned long.C: qsort не работает с 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); 
} 

Вот результат я получил:

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

Вы не собираетесь, чтобы проверить, что сравнение функции вашей? –

+0

Взрыв! Прямо там :) –

ответ

6

Вы функция сравнения неправильно. Вычитание значений без знака может обернуть значение, дающее неверный результат.

Функция должна сравнить только значения:

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

@JonathanLeffler Спасибо за int-> длинную коррекцию. Как вы относитесь к помещению пробела перед точкой с запятой? :-) – 2501

+0

Не увлекаюсь ими. У меня есть сценарий, который сообщает об этом, и исправление легко. –

+0

@JonathanLeffler Не считаете ли вы, что, поскольку точка с запятой привязана наименее сильно, ее следует отделить от оператора, как, например, присваивание '=' оператора. Почти все согласны с тем, что пространство должно быть до и после него. 'int a = 5;' vs 'int a = 5;'. Из языковой агностической точки зрения, в первом кажется, что точка с запятой связывается с числом. – 2501