gpt4 book ai didi

c - Programming Pearls 中的 qsort 函数出错?

转载 作者:太空狗 更新时间:2023-10-29 15:21:04 26 4
gpt4 key购买 nike

是我还是Programming Pearls中的这段代码?是错误的(quicksort 需要 2 个 const voids,不是吗?)如果是这样,我的解决方案是否正确?抱歉,正在学习...

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*),反之亦然。该标准允许函数指针和数据指针具有不同的大小。即使它可以在您的计算机上运行,​​也不能保证始终运行。

关于c - Programming Pearls 中的 qsort 函数出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1072083/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com