有两种明显的使用方式qsort
:在比较器中强制转换:
int cmp(const void *v1, const void *v2)
{
const double *d1 = v1, *d2 = v2;
⋮
}
qsort(p, n, sizeof(double), cmp);
或投放比较器:
int cmp(const double *d1, const double *d2)
{
⋮
}
qsort(p, n, sizeof(double), (int (*)(const void *, const void *))cmp);
我倾向于使用前者,出于美学原因,而不是其他任何原因。是否有任何技术上的原因偏爱一个?
您应避免使用后一种情况,因为这是无效的。
为了使两种功能类型兼容,返回类型必须兼容,而相应的参数类型必须兼容。Aconst void *
与不兼容,const double *
因此功能类型不兼容。通过不兼容的指针类型调用函数会导致未定义的行为。
请注意,仅仅因为两个类型可以隐式转换并不意味着它们是兼容的。取的示例const double *
和const void *
,能够不流延来进行两种类型之间的转换,然而,表示这两种类型的不需要是相同的。
这意味着aconst double *
传递给函数的方式可能与a传递给函数的方式不同const void *
。因此,通过像调用typeint (*)(const double*, const double*)
一样调用type函数,int (*)(const void*, const void*)
可能会以错误的方式传递参数。
尽管x64和ARM系统通常对所有指针类型都使用相同的表示形式,但是您可能会放弃使用前一种表示法,但是仍然无法保证。现代编译器通常会假定未定义的行为不会发生,并根据该事实进行优化。
前一种情况是正确的方法,因为函数签名与qsort
函数期望值兼容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句