Qsort比较功能

Dli*_*net 10 c sorting qsort multidimensional-array

我是C的初学者,我正在尝试理解qsort函数所需的比较函数.

第一部分:语法

一个简单的建议用法就是这个(我已经包含了一些main()代码来打印结果):

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

int values[] = { 40, 10, 100, 90, 20, 25, 12, 13, 10, 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, 10, sizeof(int), compare);
    for (n=0; n<10; n++)
    {
        printf("%d ",values[n]);
    }
    printf("\n");
    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

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

int compare (int *a, int *b)
    {
        return *a-*b; 
    }
Run Code Online (Sandbox Code Playgroud)

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

第二部分:为什么指针?

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

int compare (int a, int b)
        {
            return a-b; 
        }
Run Code Online (Sandbox Code Playgroud)

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

#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][0]);
        printf("%d ",values[n][1]);
    }
    printf("\n");
    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

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

Bil*_*eal 12

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

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

指向一种类型的函数的指针可以被转换为指向另一种类型的函数的指针并且再次返回; 结果应该等于原始指针.如果转换的指针用于调用类型与指向类型不兼容的函数,则行为未定义.

在C++中,这个程序是完全错误的:http://ideone.com/9zRYSj

它仍然"正常工作",因为该compare函数需要一对指针; 和你的特定平台上sizeof(void*)是一样的sizeof(int*),因此调用类型的函数指针int(void *, void *)这实际上包含一个指向类型的功能int(int *, int *)有效的指针类型在这个时间特定点您的特定平台上投射相同.

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

因为qsort对任何两种类型都采用一般比较函数; 不只是int.因此它不知道指针被解除引用的类型.

出于某种原因,使用多维数组,我能够逃避不使用指针,并且由于某种原因它可以工作!到底是怎么回事!

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

  1. int foo(int *a, int *b);
  2. int foo(int a[], int b[])

也就是说,数组在传递给函数时会衰减为指针.像你一样明确指定数组的长度:

int foo(int a[2], int b[2])
Run Code Online (Sandbox Code Playgroud)

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

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