这是该计划。
#include<iostream>
#include<string>
using namespace std;
struct stack
{
int inf;
stack* link;
} *start, *p;
void push(stack*, stack*, int);
void pop(stack*, stack*);
int main()
{
int s = 0;
string thing;
cin >> thing;
while (thing != "end")
{
if (thing == "push")
{
push(start, p, s);
}
if (thing == "pop")
{
pop(start, p);
}
cin >> thing;
}
return 0;
}
void push(stack *start, stack *p, int s)
{
cin >> s;
p = start;
start = new stack;
start->inf = s;
start->link = p;
cout << "pushed " << start->inf << endl;
}
void pop(stack *start, stack *p)
{
cout << "popped " << start->inf;
p = start;
start = start->link;
delete p;
}
这是一个简单的程序,允许我在堆栈中推送和弹出项目,但由于某种原因,pop()
只是不起作用。如果我在if(start)
之前添加pop
它只是跳过它,让我认为在push
完成后堆栈会以某种方式变为NULL。基本上一切都有效,直到它到达cout << "popped " << start->inf;
行,当它刚崩溃(没有错误消息)时再次让我认为堆栈在到达pop()
之前变为空。有什么建议吗?
答案 0 :(得分:1)
首先,你的两个函数的签名都很奇怪:
start
假设p
指向堆栈顶部,您应该丢弃push
。它应该是函数的局部变量,而不是参数。
其次,让我们看看p = start;
start = new stack;
start->inf = s;
start->link = p;
实施:
start
这个看起来很好。您错过的是start
被声明为堆栈指针,您正在更改函数内部的指针,这是一个值参数而不是引用。使用您当前的签名,您可以更改start
POINTS TO,而不是inf
本身。
您可以将其声明为指向堆栈的指针,并相应地更改主体(您需要双重取消引用以分配link
和&
)或通过在参数前添加pop
来使用引用参数名称。同样的情况适用于您的{{1}}功能。
答案 1 :(得分:0)
这里你如何引用指针:
void push(stack*&, stack*&, int);
void pop(stack*&, stack*&);
答案 2 :(得分:0)
之前的答案是正确的,但它们并没有真正解释原因。
这里使用的开始和p
void push(stack *start, stack *p, int s)
与此处定义的不同。
struct stack
{
int inf;
stack* link;
} *start, *p;
push
有一个全新的开头,p可能是另一个开头和p的副本,但它们不一样。可以定义推送
void push(stack *hamburger, stack *cheeseburger, int s)
对函数内部使用的变量进行相应的更改,你会发现函数的行为没有区别。
您在汉堡版push
中获得的内容是能够查看原始start
和p
。因为同时允许两个具有相同名称的变量会导致完全混淆(严重的是,哪一个被使用?)最内层的定义隐藏了所有外部定义。因此push
的{{1}}不仅不是全局定义的start
,而start
的{{1}}也阻止了对全局push
的访问。
但是,如果您定义并且不更改内容
start
start
和void push(stack *hamburger, stack *cheeseburger, int s)
{
cin >> s;
p = start;
start = new stack;
start->inf = s;
start->link = p;
cout << "pushed " << start->inf << endl;
}
不会用于任何内容,hamburger
使用全局cheeseburger
和push
现在考虑如果某人修改了您的代码并错误地遗漏了start
会发生什么。
p
p
仍然是一个有效的变量,代码仍然很乐意编译,并使用了错误的void push(stack *start, int s)
。
在重用变量名之前请仔细考虑。我喜欢标记全局变量,以便我可以看到它们何时被使用,因此它们不太可能与本地人发生冲突。对我来说,开始是gStart。它看起来很奇怪,可以脱颖而出,不太可能被意外使用。
OP的代码还不错。需要测试有效的整数输入和弹出空堆栈p