第一部分:语法
一个简单的建议使用这是(我已经包括一些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 *的比较函数会导致未定义的行为. “未定义行为”的一个有效结果是“它似乎工作”.另一个有效的结果是“它在星期二工作”或“格式化硬盘”.不要依赖这个行为.