简体   繁体   English

比较C中void指针指向的值

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

I need to compare the values of two void pointers in C. In the code below, I'm getting the console print out that they are different. 我需要比较C中两个void指针的值。在下面的代码中,我将控制台打印出来是不同的。 It seems that the comparison is between the addresses contained in these two void pointers. 似乎比较是在这两个void指针中包含的地址之间。

How can I make it so that the code compares values (ie: 1 == 1 ) of the void pointers and prints "same" ? 我怎样才能使代码比较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;
}

You have to know what type of data the void pointers really point at, coerce the pointers to point to that type, and then dereference the coerced pointers (and assume that the types are comparable using == ): 您必须知道void指针真正指向的数据类型,将指针强制指向该类型,然后取消引用强制指针(并假定使用==可以比较类型):

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

It's a lot easier just to compare the original variables: 比较原始变量要容易得多:

if (i == j)
    …

or to use correctly typed pointers: 或使用正确类型的指针:

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

What happens in the case that I do not know the type of data (assuming that an user will always pass the same type of data to be compared with my linked list delete method)? 在我不知道数据类型的情况下会发生什么情况(假设用户将始终传递与我的链表删除方法进行比较的相同类型的数据)?

Then life gets difficult. 然后生活变得困难。 Ideally you get the programmer to pass you a comparator function — see bsearch() and qsort() from the Standard C library for examples. 理想情况下,您可以让程序员向您传递比较器函数—有关示例,请参见标准C库中的bsearch()qsort()

Failing that, you need to know the size of the target type and you hope that memcmp() will do the job sufficiently well. 失败的话,您需要知道目标类型的大小,并希望memcmp()可以很好地完成这项工作。 That's far from guaranteed — it is not clear that comparing two double values with memcmp() will always produce the correct answer (it might claim different representations of NaN are different, for example), and comparing struct types with padding is fraught, and it wouldn't work correctly for your linked list data type if you're passed the nodes (it might be OK if you're passed the data fields from the two nodes). 这远不能保证-尚不清楚将两个double值与memcmp()进行比较是否总是会得出正确的答案(例如,它可能声称NaN的不同表示形式是不同的),并且比较struct类型与padding并不容易,如果您传递了节点,则对于链表数据类型将无法正常工作(如果您从两个节点传递了数据字段,则可能没问题)。

If you needed to do ordering rather than just equality (a binary search tree, for example), then the situation is worse — in that case, require the programmer to supply the comparator function. 如果您需要排序而不是仅进行相等排序(例如,二进制搜索树),那么情况就更糟了–在这种情况下,要求程序员提供比较器功能。

The pointers are different. 指针不同的。 If you are trying to compare the integers the pointers point to, then you want 如果要比较指针所指向的整数,则需要

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

u have to type cast the void pointer to type int* 您必须键入将void指针转换为int *类型

as the compiler doesnt know what type of address the pointer is pointing at, it doesnt know how many bytes to read from the pointer address and compare. 因为编译器不知道指针所指向的地址类型,所以它也不知道要从指针地址读取并比较多少字节。 try this 尝试这个

    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;

From your comments, you are tryng to implement a linked list and do not know the data type of the targets of the pointers. 根据您的评论,您正在尝试实现一个链表,并且不知道指针目标的数据类型。 Your design is wrong: with void* pointersyou simply cannot (reasonably or reliably) compare the data without knowing the type. 您的设计是错误的:使用void*指针,您根本无法(合理或可靠地)在不知道类型的情况下比较数据。 You need to approach it differently. 您需要采取不同的方法。 The best approach is to implement the linked list as a template class. 最好的方法是将链接列表实现为模板类。 Your node class will look something like 您的节点类看起来像

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

But be aware that you need to be very careful of memory management. 但是请注意,您需要非常注意内存管理。 You need to decide who is going to own and manage the objects. 您需要确定谁将拥有和管理对象。 In the class above, the user must manage the objects completely. 在上面的类中,用户必须完全管理对象。 If you want to relieve the user of this burden, use autopointers, so your nodes become something like 如果您想减轻用户的负担,请使用自动指针,这样您的节点就会变成

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

In both cases, you can compare the values via 在这两种情况下,您都可以通过

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

and this simply presumes that the T type can be compared via ==, which should be true in most cases. 这只是假设可以通过==比较T类型,这在大多数情况下应该是正确的。

Note that the suggestions of using memory compare and the like are just dangerous - such comparisons completely ignore the structure and symantics of the underlying data type. 注意,使用内存比较之类的建议只是危险的-这样的比较完全忽略了基础数据类型的结构和含义。

OK, given that this must be in C, make your nodes like 确定,因为这必须在C中,所以使您的节点像

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

and require that the user of your linked list must provide you with a pointer to a comparitor function 并要求您链表中的用户必须为您提供指向比较函数的指针

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

which is exactly what Jonathan Leffler suggested below. 这正是乔纳森·莱夫勒(Jonathan Leffler)在下面的建议。 Exactly how to structure all this depends on how your are structuring your linked list. 究竟如何构造所有这些取决于您构造链表的方式。

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

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