Qsort比较功能 [英] Qsort Comparison Function

查看:86
本文介绍了Qsort比较功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C语言的初学者,我试图了解qsort函数所需的比较函数.

I am a beginner to C and I am trying to understand the comparison function needed for the qsort function.

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

A simple suggested use is this (I have included some main() code to print the results as well):

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

我不明白为什么您需要在compare函数中所有额外的东西,所以我将其简化为:

I don't understand why you need all the extra things in the compare function so I simplified it to this:

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

这仍然有效,并且产生相同的结果.谁能向我解释我删除的内容以及为什么它仍然有效?

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

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

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

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

由于某种原因,对于多维数组,我能够不使用指针而逃脱,并且由于某种原因它起作用了!到底是怎么回事? (按每个子数组中的第二项对多维数组排序的示例代码):

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? (Example code of sorting a multidimensional array by the 2nd item in each sub array):

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

我真的很高兴多维数组排序能够正常工作,因为这仍然是我的最终目标,但是我不知道如何设法使它起作用(除了运气不好而且切碎了)代码),所以我真的很喜欢为什么我提供的一些示例可以工作,而有些却不能的解释!

I am really glad the multidimensional array sorting is working as that is my end goal anyway, but I have no idea how I managed to get it to work (other than dumb luck and chopping up the code) so I would really love some explanation as to why some of the examples I provided work, and why some don't!

推荐答案

这仍然有效,并且产生相同的结果.谁能向我解释我删除的内容以及为什么它仍然有效?

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 Pointers/8:

You are invoking undefined behavior in C. See C99 6.3.2.3 Pointers/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

In C++, this program is flat-out ill-formed: http://ideone.com/9zRYSj

由于compare函数需要一对指针,因此它仍然起作用".并且在您的特定平台上sizeof(void*)sizeof(int*)相同,因此调用int(void *, void *)类型的函数指针(实际上包含指向int(int *, int *)类型的函数的指针)有效 ,与在特定时间点在您的特定平台上投射的指针类型相同.

It still "happens to work" because the compare function expects a pair of pointers; and on your particular platform sizeof(void*) is the same as sizeof(int*), so calling a function pointer of type int(void *, void *) which in fact contains a pointer to a function of type int(int *, int *) is effectively the same as the pointer type casts on your particular platform at this particular point in time.

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

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.因此,它不知道将指针取消引用的类型.

Because qsort takes a general comparison function for any two types; not just int. So it doesn't know what type to which the pointer is dereferenced.

由于某种原因,有了多维数组,我能够不使用指针而逃脱,并且由于某种原因它起作用了!发生了什么事!

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!

这是因为以下原型相同:

This is because the following prototypes are the same:

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

也就是说,当数组衰减传递给函数时,它会变成一个指针.像您一样明确指定数组的长度:

That is, an array decays into a pointer when passed to a function. Explicitly specifying the length of the array as you did:

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

使编译器产生sizeof和其他编译时间位,以将该项目视为两个元素的数组;但是当该功能下降到计算机级别时,它仍然接受一对指针.

causes the compiler to make sizeof and other compile time bits to treat the item as a two element array; but the function still accepts a pair of pointers when it gets down to the machine level.

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

In any of these cases, passing a comparison function that does not take a pair of void *s results in undefined behavior. One valid result of "undefined behavior" is "it just seems to work". Another valid result would be "it works on Tuesdays" or "it formats the hard disk". Don't rely on this behavior.

这篇关于Qsort比较功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆