c中的链表添加到前面

c中的链表添加到前面,c,pointers,linked-list,singly-linked-list,C,Pointers,Linked List,Singly Linked List,所以我真的很困惑。我正在尝试编写一个c方法,它允许我在链表的前面添加一个新的“节点”。我以前在C++中做过这件事,没问题。我感到很沮丧,因为在编写代码之后,我非常确定我是对的,我四处看看,基本上我发现的每一个地方都告诉我要做我已经准备好做的事情…我将提供代码和一步一步的地址和变量值。代码如下: 所讨论的真正功能是: void addToBeginning(int value, struct node* root){ struct node* newNode; newNode =

所以我真的很困惑。我正在尝试编写一个c方法,它允许我在链表的前面添加一个新的“节点”。我以前在C++中做过这件事,没问题。我感到很沮丧,因为在编写代码之后,我非常确定我是对的,我四处看看,基本上我发现的每一个地方都告诉我要做我已经准备好做的事情…我将提供代码和一步一步的地址和变量值。代码如下:

所讨论的真正功能是:

void addToBeginning(int value, struct node* root){
    struct node* newNode;
    newNode = malloc( sizeof(struct node));
    newNode->value = value;
    newNode->next = root;
    root = newNode;
}
但这里是完整的代码。我删除了一些东西以使其更简洁(回答这个问题不需要的东西,如getLength(…)和addToPos(…)

行…因此我将包括调试步骤中获得的地址: 所以…在
addToBeginning(int-value,struct-node*root){…}
函数中,我将逐步介绍:

在执行以下命令后:

struct node* newNode;
newNode = malloc( sizeof(struct node));
newNode->value = value;
newNode->next = root;
root = newNode;
root和newNode的地址和值为:

root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 0
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 2
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
root = 0x0000000100103cc0
root->next = 0x0000000100103c60
root->value = 2
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
在执行以下命令后:

struct node* newNode;
newNode = malloc( sizeof(struct node));
newNode->value = value;
newNode->next = root;
root = newNode;
root和newNode的地址和值为:

root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 0
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 2
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
root = 0x0000000100103cc0
root->next = 0x0000000100103c60
root->value = 2
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
在执行以下命令后:

struct node* newNode;
newNode = malloc( sizeof(struct node));
newNode->value = value;
newNode->next = root;
root = newNode;
root和newNode的地址和值为:

root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 0
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 2
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
root = 0x0000000100103cc0
root->next = 0x0000000100103c60
root->value = 2
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
在执行以下命令后:

struct node* newNode;
newNode = malloc( sizeof(struct node));
newNode->value = value;
newNode->next = root;
root = newNode;
root和newNode的地址和值为:

root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 0
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = NULL
newNode->value = 2
root = 0x0000000100103c60
root->next = 0x0000000100103c70
root->value = 4
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
root = 0x0000000100103cc0
root->next = 0x0000000100103c60
root->value = 2
newNode = 0x0000000100103cc0
newNode->next = 0x0000000100103c60
newNode->value = 2
我意识到问题在于
*root
是通过引用传递的,因此我需要做的是更改存储在位置
0x0000000103C60
中的对象的值,因此对于如何执行此操作的任何建议都将不胜感激。

void addToBeginning(int value, struct node* root){
    struct node* newNode;
    (...)
    root = newNode;
}

struct node *root2;
addToBeginning(2, root2);
将新地址分配给本地根指针。此指针的值与原始根指针的值相同,但它是它的副本。所以在函数返回后,在函数内部更改该变量对原始根没有影响

相反,您必须逐个指针传递指针:

void addToBeginning(int value, struct node **root){
    struct node* newNode;
    (...)
    *root = newNode;
}

struct node *root2;
addToBeginning(2, &root2);

补充资料 这可能令人惊讶。当您想要更改原始变量时,是否总是将指针传递给函数?嗯,是的,但它是指向的变量,而不是指针本身。在这里,假设您的原始函数使用指针(不是指向指针的指针),您仍然可以使用
*root2=x
更改由root2指向的原始节点,或者使用
root2->member=y
更改该节点的成员。这会起作用,因为您更改了指向的变量(即使它们是指针-您可以更改这些指针[它们指向的地址],因为您有一个指向它们的指针,并且您取消了对该指针的引用)

这同样适用于作为变量的指针。如果要更改原始指针,必须指向它并更改所指向的变量,在这种情况下为原始指针

你需要

void addToBeginning(int value, struct node** root)
对于
root


这允许您在此函数之外修改
root

您可以在插入函数中修改
root
的本地副本;您不会修改调用代码中的相应值。从函数返回列表的新标题,或者将指向根节点的指针的指针传递给函数,以便可以在函数中修改指向根节点的指针。有很多,很多,像这样的问题,在这里有相同的基本问题,所以,宾果。谢谢@JonathanLeffler一个指向指针的指针就是我想要听到的!天啊!!!一个带有调试步骤的链表问题!投票表决。我要买一张彩票。注意
main()
中创建节点的代码是
struct node*root2;root2=malloc(sizeof(struct node));root2->value=4;root2->next=NULL
并且在
addToBeginning()
addToEnd()
代码中几乎有相同的代码。这可能应该抽象为
struct node*newElement(int值)函数。然后,您可以在一个位置添加对
malloc()
故障的错误检查,而不必在三个不同的位置进行检查