Qsort比较功能

我是C的初学者,我正在努力了解qsort函数所需的比较功能.

第一部分:语法

一个简单的建议使用这是(我已经包括一些main()代码打印结果):

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

int values[] = { 40,10,100,90,20,25,12,13,40 };

int compare (const void *a,const void *b)
{
    const int *ia = (const int *)a; // casting pointer types 
    const int *ib = (const int *)b;
    return *ia  - *ib; 
}

int main ()
{
    int n;
    for (n=0; n<10; n++)
    {
        printf("%d ",values[n]);
    }
    printf("\n");
    qsort (values,sizeof(int),compare);
    for (n=0; n<10; n++)
    {
        printf ("%d ",values[n]);
    }
    printf("\n");
    system("pause");
    return 0;
}

我不明白为什么你需要比较功能中的所有额外的东西,所以我把它简化为:

int compare (int *a,int *b)
    {
        return *a-*b; 
    }

这仍然有效,并产生相同的结果.任何人都可以向我解释什么我删除了,为什么它仍然有效?

第2部分:为什么指针?

另外,我真的需要使用指针吗?为什么我不能直接比较“a”和“b”(这不工作):

int compare (int a,int b)
        {
            return a-b; 
        }

由于某种原因,使用多维数组,我能够避免使用指针,并且由于某种原因它可以工作!到底是怎么回事! (每个子数组中第二个项目排序多维数组的示例代码):

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

int values[7][3] = { {40,55},{10,52},{100,8},{90,90},{20,91},{25,24} };

int compare (int a[2],int b[2])
{
    return a[1] - b[1];
}

int main ()
{
    int n;
    for (n=0; n<6; n++)
    {
        printf ("%d,",values[n][0]);
        printf ("%d ",values[n][1]);
    }
    printf("\n");
    qsort (values,6,sizeof(int)*3,compare);
    for (n=0; n<6; n++)
    {
        printf ("%d,values[n][1]);
    }
    printf("\n");
    system("pause");
    return 0;
}

我真的很高兴多维数组排序正在工作,因为这是我的最终目标,但我不知道我如何设法让它工作(除了愚蠢的运气和剁碎的代码),所以我真的很喜欢一些解释为什么我提供的一些例子是工作,为什么有些不行!谢谢!

解决方法

This still works,and produces the same results. Can anyone explain to me what I removed,and why it still works?

您正在C中调用未定义的行为.请参阅C99 6.3.2.3指针/ 8:

A pointer to a function of one type may be converted to a pointer to a function of another
type and back again; the result shall compare equal to the original pointer. If a converted
pointer is used to call a function whose type is not compatible with the pointed-to type,
the behavior is undefined.

在C,这个计划是扁平化的:http://ideone.com/9zRYSj

它仍然“正常工作”,因为比较函数需要一对指针;并且在你的特定平台上,sizeof(void *)与sizeof(int *)相同,所以调用一个类型为int(void *,void *)的函数指针,其实际上包含一个指向int(int *,int *)与在特定时间点上的特定平台上的指针类型有效地相同.

Additionally,do I really need to use pointers? Why can’t I just compare “a” and “b” directly like so (this does NOT work):

因为qsort对于任何两种类型都具有一般的比较功能;不只是int所以它不知道什么类型的指针被取消引用.

For some reason,with a multidimensional array,I was able to get away with NOT using pointers and for some reason it worked! what is going on!

这是因为以下原型是相同的:

> int foo(int * a,int * b);
> int foo(int a [],int b [])

也就是说,一个数组在传递给一个函数时会衰减成一个指针.按照您的方式明确指定数组的长度:

int foo(int a[2],int b[2])

导致编译器将sizeof和其他编译时间位视为两个元素数组;但是当它降到机器级别时,该功能仍然接受一对指针.

在任何这些情况下,传递不采用一对void *的比较函数会导致未定义的行为. “未定义行为”的一个有效结果是“它似乎工作”.另一个有效的结果是“它在星期二工作”或“格式化硬盘”.不要依赖这个行为.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...