你能在 C 中布尔小于比较 2 个 void * 值吗?

发布于 2024-11-28 21:44:50 字数 147 浏览 0 评论 0原文

我正在对列表中的一些内存指针进行 qsort() 操作,以便稍后在函数中对它们进行 bsearch。我的问题是,我是否需要将这些值类型转换为 const void * 以外的其他值才能在 C 中进行合法比较?我可以直接进行转换并让编译器告诉我,但我有一种感觉,这可能取决于编译器。

I'm qsort()ing some memory pointers in a list to allow a bsearch of them later in a function. My question is, do I need to type cast those values to something other than const void * to do a legal comparison in C? I could just do the conversion and let the compiler tell me, but I have a feeling that this might be compiler dependent.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

疾风者 2024-12-05 21:44:50

比较很好,算术和取消引用则不行(因为您不知道基础数据的大小)。所以是的,您可以很好地比较 void 指针(a)

但是,请记住,您通常不会比较传递给 qsort 比较函数的指针,除非您想对它们的地址进行排序。但是,由于它们已经按该顺序排序(作为数组),因此没有太多用例:-)

您通常将 void 指针转换为特定指针,然后比较它们指向的内容. 类似于:

int compfn (const void *p1, const void *p2) {
    const char *str1 = *((const char **)(p1));
    const char *str2 = *((const char **)(p2));
    return strcmp (str1, str2);
}

您不必创建像 str1str2 这样的临时变量(即使任何像样的编译器都会优化它们)。除了轻微的可读性问题之外,没有任何问题:

int compfn (const void *p1, const void *p2) {
    return strcmp (*((const char **)(p1)), *((const char **)(p2)));
}

(a) 遵循正常规则,指针必须都指向同一数组的元素或指向该数组之外的元素 - 其他任何内容都是未定义的。为了完整起见,我提到了这一点,但是,如果您使用 qsort,那么您无论如何都会处理数组。

Comparisons are fine, arithmetic and dereferencing are not (because you don't know the size of the underlying data). So yes, you can compare void pointers quite well (a).

However, keep in mind that you don't usually compare the pointers passed to a qsort comparison function, unless you want to sort on their addresses. But, since they'll be sorted in that order already (being an array), there's not much of a use case for that :-)

You generally cast the void pointers to a specific pointer and then compare what they point to. Something like:

int compfn (const void *p1, const void *p2) {
    const char *str1 = *((const char **)(p1));
    const char *str2 = *((const char **)(p2));
    return strcmp (str1, str2);
}

You don't have to create temporaries like str1 and str2 (even though any decent compiler would optimise them out anyway). Other than a slight readability issue, there's nothing wrong with:

int compfn (const void *p1, const void *p2) {
    return strcmp (*((const char **)(p1)), *((const char **)(p2)));
}

(a) Subject to the normal rules that the pointers must both point to elements of the same array or one beyond that array - anything else is undefined. I mention that for completeness but, if you're using qsort, you'll be working on an array anyway.

平定天下 2024-12-05 21:44:50

通常您希望在比较函数中执行类似的操作

int compare(const void *a, const void *b) 
{
    int aa = *(int *)a;
    int bb = *(int *)b;
    return aa - bb;
}

,并将 void * 转换为适当的类型(对于 int 只是一个示例)。

与 const void * 类型进行比较是有效的,但这是地址的比较。如果这是您想要的,那么如果上面(人为的示例)不适用(取决于您要比较的内容),那也没关系。

编辑:对于你的情况

int compare(const void *a, const void *b)
{
    if (a < b) return -1;
    else if (a == b) return 0;
    return 1;
}

我这样做的原因是因为地址的 sizeof(unsigned long) 大于 int 的大小,如果你以某种方式溢出 int ,这可能会导致问题。

Usually you want to do something like this in your compare function

int compare(const void *a, const void *b) 
{
    int aa = *(int *)a;
    int bb = *(int *)b;
    return aa - bb;
}

and convert the void * to the appropriate type (with int's it's just an example).

It is valid to compare to const void * types but this is a comparison of the address. If this is what you want then that's fine if not the above (contrived example) applies (depending on what you're comparing).

EDIT: For your case

int compare(const void *a, const void *b)
{
    if (a < b) return -1;
    else if (a == b) return 0;
    return 1;
}

The reason I do it this way is because addresses are sizeof(unsigned long) which is greater than the size of an int which could cause an issue if you overflow the int somehow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文