错误qsort函数在编程珠玑?
-
21-08-2019 - |
题
只是我或该代码在编程珍珠是错误的(快速排序要2个const的空隙,不是吗?)如果是这样,我的解决方案吗?道歉,刚学...
int wordncmp(char *p, char* q)
{ int n = k;
for ( ; *p == *q; p++, q++)
if (*p == 0 && --n == 0)
return 0;
return *p - *q;
}
int sortcmp(char **p, char **q)
{ return wordncmp(*p, *q);
}
...
qsort(word, nword, sizeof(word[0]), sortcmp);
这是一个解决方案?
int sortcmp(const void *p, const void *q)
{ return wordncmp(* (char * const *) p, * (char * const *) q);
}
解决方案
在第一个代码示例可能会与几乎任何编译器和CPU工作;然而,这在技术上是未定义的行为,如果你按照C标准的信。
正如你所说,的最后一个参数qsort()
是指向服用类型const void*
的两个参数的函数。 sortcmp
需要不同的参数。你的编译器的应的给你一个关于不兼容的类型签名什么的警告。在任何情况下,流延正在从一种类型的功能到另一种类型的函数来执行。
在C标准规定,可以投函数指针到与不同类型的其它函数指针,但不能解除引用并调用铸造函数指针。不过,如果你再投的函数指针回到原来的类型,然后调用已定义的行为 - 它调用原来的功能
既然你从int (*)(char**, char**)
铸造到int (*)(const void*, const void*)
,然后最终qsort()
被调用的比较器功能而无需进行转换回int (*)(char**, char**)
,这是不确定的行为。
不过,因为几乎在所有的架构,一个char **
和const void*
都代表相同的方式,函数调用将几乎总是工作。
如果你想定义的行为,你必须确保你的比较函数具有正确的类型签名,然后,就可以把参数传递给正确的类型。您的解决方案是完全正确的,并且不违反C标准那里。干得好上const
-正确性 - 很多人不明白到底是什么char * const *
手段
您也应该wordncmp()
采取const char*
的参数,因为你不修改的参数。
边注:也可以在技术上不是一个函数指针转换为一个数据的指针(例如,void*
)或反之亦然。该标准允许函数指针和数据指针有不同的尺寸。即使它的工作原理您的计算机上,它不能保证总是工作。
其他提示
您是正确的,对于sortcmp
不匹配qsort
预期的签名。您的修正是正确的。 wordcmp
还应该const
,正确的,因为你是在技术上失去一些const
岬的沿途。
int wordncmp(const char *p, const char* q)