我试图用 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 的指针时,我发现它与原始头指针相同,因此实际指针似乎在方法中。我不明白这里发生了什么,所以如果有人能解释为什么头指针没有更新,即使那里有相同的指针,那也很好。
我认为它应该可以工作,因为如果你有一个 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 内核如何高效实现 lists using struct embedding 的精彩文章.很高兴!
关于c - C 中指向指针的指针问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54340755/