C:qsort似乎无法处理unsigned long类型

3
请问以下示例有什么问题?我从这里获取了它,并用unsigned long替换了int。我还更改了cmpfunc以正确处理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
你不打算测试一下你的比较函数吗? - Michael Foukarakis
砰!就在那里 :) - Frederico Schardong
1个回答

9

你的比较函数不正确。无符号值相减可能会导致数值溢出,从而得到错误的结果。

该函数应仅比较数值:

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

@JonathanLeffler 感谢您对 int->long 的更正。您对在分号前放置空格的看法如何? :-) - 2501
我也不喜欢它们。但是我有一个可以报告这些问题的脚本,而且修复很容易。 - Jonathan Leffler
@JonathanLeffler 您不认为分号的绑定力最弱,因此应该将其与语句分开,就像赋值=运算符一样。几乎所有人都同意在其前后加上空格。 int a = 5;int a = 5 ;。从语言无关的角度来看,在前者中,分号似乎与数字绑定。 - 2501
@JonathanLeffler 为什么不呢?你能详细说明一下吗? - 2501
这不是标准的C语言风格——请看C标准或K&R等。在正统写作中,你不会在句号、逗号或分号前加空格。你可以在自己的代码上随意尝试,但不要在我负责的代码上尝试。 - Jonathan Leffler
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接