繁体   English   中英

指针到C指针的麻烦

[英]Trouble With Pointers to Pointers in C

我试图在C中编写某种列表,而没有为列表的开头创建全局变量,但遇到了一些麻烦。

我的代码最初是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

struct Node {
    char *data;
    struct Node *next;
};

struct Node *init(struct Node *head) {
    head = malloc(sizeof(struct Node));
    head->data = "abc";
    head->next = NULL;

    return head;
}

struct Node *getHead(struct Node *head) {
    struct Node *retNode = NULL;

    if (head != NULL) {
        retNode = head;
        head = head->next;
    }

    return retNode;
}

int main(int argc, char **argv) {
    struct Node *head;
    head = init(head);
    printf("Head pointer before method:%p\n", head);

    getHead(head);
    printf("Head pointer after method:%p\n", head);
}

产生输出:

Head pointer before method:0x7fffd36ad260  
Head pointer after method:0x7fffd36ad260

我以为这是失败的,因为C是通过值传递的,这使我认为方法内部显示了具有不同指针的相同副本。 但是,当我检查方法中指向Head的指针时,我发现它与原始的head指针相同,因此看起来实际的指针在方法中。 我不明白这里发生了什么,所以如果有人可以解释为什么即使存在相同的指针也不会更新头部指针的原因。

我认为它应该工作,因为如果您有一个swap(int * a,int * b)方法,并且实际的指针是从main发送的,则内部进行的更改将同时影响外部的变量。 在网上看了之后,人们说要为此使用指针,尽管我似乎无法正常工作。

尝试将其编码如下:

//... same code as before for other methods
struct Node *getHead(struct Node **head)
{
    struct Node *retNode = NULL;

    if (head != NULL)
    {
        retNode = *head;
        *head = *head->next;
    }

    return retNode;
}

int main(int argc, char **argv)
{
    struct Node *head;
    head = init(head);
    printf("Head pointer before method:%p\n", head);

    getHead(&head);
    printf("Head pointer after method:%p\n", head);
} 

虽然在尝试编译时会遇到错误:

pointers.c:50:22: error: ‘*head’ is a pointer; did you mean to use ‘->’?
         *head = *head->next;

我也很茫然为什么会引发此错误。

就像其他人已经指出的那样,由于运算符的优越性,您必须将*head放在括号中。

我有什么理解的是,为什么你覆盖问题head与它的后继者? 函数getHead应该更好地称为removeHead吗?

还要注意,函数init head参数无效,因为它会被以下malloc覆盖。

我还建议阅读有关Linux内核如何使用结构嵌入实现有效列表的出色文章。 很高兴!

将双指针传递给getHead因为您试图在调用getHead的范围内更新head

struct Node *getHead(struct Node **head) {
    struct Node *retNode = NULL;

    if (head != NULL && *head != NULL) {
        retNode = *head;
        *head = (*head)->next;
    }

    return retNode;
}

第一次尝试之前和之后方法head的值相同的原因是,您从未更改mainhead的值。 函数getHead更改其指针head本地副本。 因此,如果您第一次尝试在getHead内打印head ,您将看到它指向另一个地址。

暂无
暂无

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

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