void push(stack *head, int valuee)
{
if(head->next==NULL && head->value==-1)
{
head->value = valuee;
printf("First element %d insertedn",valuee);
}
else
{
stack *temp = new stack;
temp->value = valuee;
temp->next = head;
head = temp;
printf("Element %d insertedn",valuee);
}
}
第一个元素已正确插入,但是当我继续插入元素时,第一个元素之后没有插入任何元素。在某处阅读我必须将指针传递到堆栈指针的地方,但我在后缀中缀问题中做了同样的事情,它在那里工作。在这里帮助我解决这个问题。非常感谢提前提供的任何帮助
以前的中缀后缀示例,该后缀正在正常工作
void push(char c, stack *node)
{
stack *B = (stack *)malloc(sizeof(stack));
if (node->next == NULL)
{
node->next = B;
B->value = c;
B->next =NULL;
}
else
{
B->next = node->next;
node->next = B;
B->value = c;
}
}
你可以像这样更改函数
stack* push(stack *head, int valuee)
//return void to stack *
return head;
//In the end return the new head
它会起作用。像这样调用推送
head = push(head,value);
为什么需要指针到指针?
你想修改指针的内容,所以如果你只传递一个指向函数的指针,它是通过复制传递的,所以你实际上不能修改它。
在中缀前缀的情况下,您必须没有修改您只会读取它的字符串,因此不需要指向指针的指针。
对于 if
语句else
部分中的以下代码行:
head = temp;
你的意图是改变head
,换句话说,改变head
所指向的内容。但是,指针作为值传入,就像其他变量一样。换句话说,假设我在其他地方调用push
函数。为简单起见,假设我在 main
函数中调用它,如下所示:
int main()
{
stack *headOfStack = new stack;
// suppose this next push triggers the else portion of the push code
push(headOfStack, 6);
}
现在,在执行 push(headOfStack, 6);
语句后,您的意图是期望headOfStack
指向一个新的"堆栈节点",其中包含值 6
。现在,headOfStack
是指向 stack 类型的变量的指针。它存储一个内存地址。您可以将内存地址视为某个整数。当我们调用 push
时,我们将headOfStack
的内容(headOfStack
的内容是内存地址(复制到 push
函数的局部变量head
中。因此,当:
head = temp;
执行,我们将temp
的内容分配给head
。什么是temp
?它是指向类型 stack
的变量的指针。换句话说,temp
的值是一个内存地址。所以head = temp;
只是将temp
中包含的内存地址分配给局部变量head
。push
函数中的局部变量head
和main
函数中的headOfStack
变量是两个完全不同的变量,具有不同的内存地址。如果我的解释到目前为止是清楚的,这意味着当我们修改push
函数中的head
时,main
中的headOfStack
变量是完全不变的。
在这种情况下,您要做的是:
void push(stack **headPtr, int valuee)
{
// this will get the actual pointer we are interested in
stack *head = *headPtr;
if(head->next==NULL && head->value==-1)
{
head->value = valuee;
printf("First element %d insertedn",valuee);
}
else
{
stack *temp = new stack;
temp->value = valuee;
temp->next = head;
// mutation is done here
*headPtr = temp;
printf("Element %d insertedn",valuee);
}
}
以及它的用法,使用我们虚构的main
函数:
int main()
{
stack *headOfStack = new stack;
// notice the use of &headOfStack instead of headOfStack
push(&headOfStack, 6);
}
请记住,指针存储内存地址,指针只是变量,它们也有内存地址。要改变指针(更改指针指向的内容(,只需将其内存地址传递给函数即可。
希望对您有所帮助!
编辑有问题的新编辑
void push(char c, stack *node)
{
stack *B = (stack *)malloc(sizeof(stack));
if (node->next == NULL)
{
node->next = B;
B->value = c;
B->next =NULL;
}
else
{
B->next = node->next;
node->next = B;
B->value = c;
}
}
对于这个版本的push
,它所做的基本上是:
如果
node->next == NULL
,则node
没有后继节点,则将其后继节点设置为新分配的节点,值为c
否则,
node->next != NULL
和node
有一些继任者。然后,我们将新分配的节点B
设置为node
的后继节点,并将node
的原始后继节点设置为B
的后继节点。或者换句话说,它将node
与其后继节点之间的新节点拼接B
(值为c
(。
我发现很难解释这一点,但一个简单的解释是,这个push
不会改变node
所指的内容。我们没有表现出改变node
的意图。我认为涉及B
的东西应该是可以理解的,所以让我们专注于node->next
作业。
我假设stack
是一个看起来像这样的结构:
struct stack {
char value;
struct stack *next;
};
现在,假设在我们的main
函数中,我们有一个stack
:
stack x;
请注意,x
不是指针。我想我们都同意,做x.value = something
和x.next = something
会改变这些领域。
现在,让我们看看这个:
stack *y = malloc(sizeof(struct stack));
我们知道y
将地址存储到实际struct stack
(实际struct stack
在 *y
(。因此,y->value = something
和y->next = something
将改变这些字段。
所以希望你能明白为什么node->value
作业有效。本质上node
包含一个实际struct stack
的地址,其值为 *node
。通过指针语法,node->value
和node->next
赋值将更改node
的内容。
我知道这不是一个很好的解释。但只需编写更多代码。当我第一次开始使用 C 时,指针让我感到困惑。我认为这些天,我仍然会被 2 或 3 层间接层所迷惑,并且我遇到了一些非常讨厌的指针错误。只是多练习...总有一天你会真正得到它。我知道这是他们都说的,但这是真的。