繁体   English   中英

比较C中void指针指向的值

[英]Comparing values pointed at by void pointers in C

我需要比较C中两个void指针的值。在下面的代码中,我将控制台打印出来是不同的。 似乎比较是在这两个void指针中包含的地址之间。

我怎样才能使代码比较void指针的值(即: 1 == 1 )并打印"same"

int main(void)
{
    int i = 1;
    int j = 1;
    void *pi = &i;
    void *pj = &j;
    if (pi == pj) {
        printf("same.\n");
    } else {
        printf("different.\n");
    }
    return 0;
}

您必须知道void指针真正指向的数据类型,将指针强制指向该类型,然后取消引用强制指针(并假定使用==可以比较类型):

if (*(int *)pi == *(int *)pj)
    printf("same.\n");
else
    printf("different.\n");

比较原始变量要容易得多:

if (i == j)
    …

或使用正确类型的指针:

int *pi = &i;
int *pj = &j;
if (*pi == *pj)
    …

在我不知道数据类型的情况下会发生什么情况(假设用户将始终传递与我的链表删除方法进行比较的相同类型的数据)?

然后生活变得困难。 理想情况下,您可以让程序员向您传递比较器函数—有关示例,请参见标准C库中的bsearch()qsort()

失败的话,您需要知道目标类型的大小,并希望memcmp()可以很好地完成这项工作。 这远不能保证-尚不清楚将两个double值与memcmp()进行比较是否总是会得出正确的答案(例如,它可能声称NaN的不同表示形式是不同的),并且比较struct类型与padding并不容易,如果您传递了节点,则对于链表数据类型将无法正常工作(如果您从两个节点传递了数据字段,则可能没问题)。

如果您需要排序而不是仅进行相等排序(例如,二进制搜索树),那么情况就更糟了–在这种情况下,要求程序员提供比较器功能。

指针不同的。 如果要比较指针所指向的整数,则需要

if ( *(int*)pi == *(int*)pj ) {
    //some code...
}

您必须键入将void指针转换为int *类型

因为编译器不知道指针所指向的地址类型,所以它也不知道要从指针地址读取并比较多少字节。 尝试这个

    int i = 2;
    int j = 1;
    void *pi = &i;
    void *pj = &j;
    if ( (*(int*)(pi)) == (*(int*)(pj)) ) 
    {
        printf("same.\n");
    } else 
    {
        printf("different.\n");
    }
    return 0;

根据您的评论,您正在尝试实现一个链表,并且不知道指针目标的数据类型。 您的设计是错误的:使用void*指针,您根本无法(合理或可靠地)在不知道类型的情况下比较数据。 您需要采取不同的方法。 最好的方法是将链接列表实现为模板类。 您的节点类看起来像

template <typename T> class Node
{
    private:
        T *m_pValue;
        Node *m_prev;
        Node *m_next;
    ...
}

但是请注意,您需要非常注意内存管理。 您需要确定谁将拥有和管理对象。 在上面的类中,用户必须完全管理对象。 如果您想减轻用户的负担,请使用自动指针,这样您的节点就会变成

template <typename T> class Node
{
    private:
        std::auto_ptr<T> m_pValue;
        Node *m_prev;
        Node *m_next;
    ...
}

在这两种情况下,您都可以通过

Node rhs, lhs;
*(lhs.m_pValue) == *(rhs.m_pValue);

这只是假设可以通过==比较T类型,这在大多数情况下应该是正确的。

注意,使用内存比较之类的建议只是危险的-这样的比较完全忽略了基础数据类型的结构和含义。

确定,因为这必须在C中,所以使您的节点像

struct node
{
    void * m_pValue;
    node * m_pPrev;
    node * m_pNext;
}

并要求您链表中的用户必须为您提供指向比较函数的指针

int (comparitor*)(void* lhs, void* rhs);

这正是乔纳森·莱夫勒(Jonathan Leffler)在下面的建议。 究竟如何构造所有这些取决于您构造链表的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM