【问题标题】:C void pointers and pointer comparisonC void 指针和指针比较
【发布时间】:2012-07-01 10:42:17
【问题描述】:

我有以下函数可以从 C 中的链表中删除通用数据:

void removeData(void *data, struct accList *theList)
{
    struct accListNode* cur = theList->head;
    struct accListNode* prev = NULL;

    for(; cur != NULL; prev = cur, cur = cur->next)
    {
        if(cur->data == data)
        {
            if(cur == theList->head)
            {
               theList->head = cur->next;
            }
            if(cur == theList->tail)
            {
                theList->tail = prev;
            }
            if(prev != NULL)
            {
                prev->next = cur->next;
            }
            free(cur);
            return;
        }
    }
}

cur->data == data背后的含义是什么?

由于我的数据是通用的 (void*),这对任何原始类型和任何结构类型意味着什么?

例如,考虑员工结构:

struct employee
{
    char name[20];
    float wageRate;
};

如果数据是struct employee* 类型,语句cur->data == data 将如何工作? 由于 data 是指向结构的第一个内存地址的指针,我只是比较指针地址吗?

【问题讨论】:

  • 您不是在比较指针地址(例如&data),而是在比较指针,即地址。

标签: c pointers struct comparison void-pointers


【解决方案1】:
cur->data == data

将指针 cur->data 与指针 data 进行比较。您正在比较它们的值,而不是它们的地址。指针是和其他变量一样的变量。它有一个地址(即&some_ptr)和一个值(即它所指事物的地址)。

请注意,其他类型的比较(即<>>=<=)会导致未定义的行为,除非指针指向同一数组的元素或指向末尾的元素(不是这样这样做是有意义的,除非你知道它们指向的是驻留在同一块连续内存中的“对象”,但仍然如此)。

【讨论】:

  • 所以我是比较cur->data和data指向的值的地址?
  • @CodeKingPlusPlus:是的,这些地址是指针的值。指针本身仍然需要内存来存储,所以它们有自己的地址,但some_ptr&some_ptr 并不等价。
  • 我想比较通用数据的值。这真的可能吗?似乎我必须添加一个额外的参数,调用者必须提供一个指向定义泛型类型相等性的函数的指针。这看起来对吗?
  • @Jack:等式比较是有效的,其他比较(即<>)会导致未定义的行为,除非指针指向同一个数组对象的元素或指向末尾的元素。
【解决方案2】:

我猜你没有写 removeData()?如果不是,那我的解释是:

removeData() 旨在从链表中删除特定条目(即 *data),而不是内容等于 *data 的条目。所以 removeData() 的调用者必须已经知道他们想要 free() 的条目在哪里。他们可以自己释放()它,但这并不好,因为链表仍然包含指向它的指针,并且可能链表的其他用户会认为释放()的对象仍然有效(他们会没有理由不相信,没有任何其他计划可以告诉他们)。

如果您想要一个函数在列表中搜索其内容与 *data 的内容匹配的条目(但与 *data 不在同一内存中),那么您需要为每个条目编写一个版本的 removeData()这样的类型,并且您的 accList 要么需要是同质的(包含该类型的所有对象),要么 accList 还需要包含每个条目类型的一些指示,可能作为枚举,以及 removeData() 的每个版本(一个对于每种类型)将需要跳过与其自身类型不匹配的元素。

【讨论】:

    【解决方案3】:

    cur->data == data 背后的含义是什么?

    代码正在检查两个指针​​是否是同一个指针

    由于我的数据是通用的 (void*) 这对于任何原始数据意味着什么 类型和任何结构类型?

    如果数据是类型,语句 cur->data == data 将如何工作 结构员工*?

    没什么,比较的结果是一样的

    由于数据是指向结构的第一个内存地址的指针 我只是比较指针地址吗?

    不,你在比较指针

    【讨论】:

    • @CodeKingPlusPlus 是的,它们只是地址,实际上它们是内容为地址的变量
    • 我想要的是比较这些指针的“值”。似乎我必须向我的函数添加一个额外的参数,以便调用者可以提供一个指向描述这种泛型类型的“相等”的函数的指针。这看起来对吗?
    • 您想检查cur->datadata 是否具有相同的值(因此它们可能是不同的“对象”但具有相同的值)或者它们是否是相同的变量?在第一种情况下,您的解决方案应该可以工作并且它是一个非常有效的解决方案,在第二种情况下,比较两个地址应该可以工作,因为两个指针都指向同一个“对象”
    【解决方案4】:

    您正在比较指针本身,而不是指向的结构。

    【讨论】:

    • 这些指针只是地址,对吧?所以我的比较对任何事情都没有好处
    • @CodeKingPlusPlus 好吧,这取决于您是首先从列表中获得指针,还是只是想删除与指向的东西相同的任何内容。很可能是后者。
    猜你喜欢
    • 2014-11-03
    • 2014-09-08
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    相关资源
    最近更新 更多