我正在为我的数据结构类创建自己的堆栈.对于我们的任务,我们使用赋值将实时中缀方程转换为后缀方程.
我认为我的程序:
输入
确定它是否为数字或数字(操作数)
打印输出
确定输入是否为运算符(+, - ,/,*)
添加到堆栈或打印输出,具体取决于堆栈优先级
相反,它会按预期打印出操作数,但是当我进入运算符时出现此错误
>.../dorun.sh line 33: 4136 Segmentation fault <core dumped> sh "$<SHFILE>"
#include <vector>
using namespace std;
class DishWell{
public:
char ReturnEnd(){
return Well.back();
}
void Push(char x){
Well.push_back(x);
}
void Pop(){
Well.pop_back();
}
bool IsEmpty(){
return Well.empty();
}
private:
vector<char> Well;
};
#include <iostream>
bool Precidence(char Input, char Stack){
int InputPrecidence,StackPrecidence;
switch (Input){
case '*':
InputPrecidence = 4;
break;
case '/':
InputPrecidence = 4;
break;
case '+':
InputPrecidence = 3;
break;
case '-':
InputPrecidence = 3;
break;
case '(':
InputPrecidence = 2;
break;
default:
InputPrecidence = 0;
}
switch (Stack){
case '*':
StackPrecidence = 4;
break;
case '/':
StackPrecidence = 4;
break;
case '+':
StackPrecidence = 3;
break;
case '-':
StackPrecidence = 3;
break;
case '(':
StackPrecidence = 2;
break;
default:
StackPrecidence = 0;
}
if(InputPrecidence>StackPrecidence) return true;
else return false;
}
int main(int argc, char** argv) {
DishWell DishTray;
char Input;
bool InputFlag;
InputFlag = true;
while(InputFlag){
cin>>Input;
if((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))|| (Input>='0'&&Input<='9')))//If Digit or Number
cout<<Input;
if((Input=='*'||Input=='/'||Input=='+'||Input=='-')){//if operand
if(Precidence(Input,DishTray.ReturnEnd()))
DishTray.Push(Input);
else if(!Precidence(Input,DishTray.ReturnEnd()))
cout<<Input;
}
else if(!((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))|| (Input>='0'&&Input<='9')))||((Input=='*'||Input=='/'||Input=='+'||Input=='-')))//if not digit/numer or operand
InputFlag = false;
}
while(!DishTray.IsEmpty()){
cout<<DishTray.ReturnEnd();
DishTray.Pop();
}
return 0;
Run Code Online (Sandbox Code Playgroud)
我知道,我的代码很长,但我很感激帮助.特别是效率或未来编码的任何时候.
再次感谢
PS Zemoudeh博士,这是你的学生Macaire
我将扩展Rup的答案来回答你没有问过的问题,但更重要的是: 我怎样才能找到我的程序崩溃的位置?
一种方法是在整个程序中放置std::cout或printf声明.在每个函数的开头写一个声明,"function x enter",最后说"function x exit".运行你的程序,当它崩溃时,你会看到它所处的功能.此时,你可以添加行来打印每个变量的内容,以找出出错的地方.
另一种方法是使用调试器,如gdb.
首先,使用-g开关编译程序以启用调试信息.
linux@linux-ubuntu:~/t$ g++ prog.cpp -o prog -g
Run Code Online (Sandbox Code Playgroud)
接下来,告诉调试器gdb运行您的程序.
linux@linux-ubuntu:~/t$ gdb ./prog
Run Code Online (Sandbox Code Playgroud)
在gdb提示符下,键入run以启动您的程序.我进去4*(3+2)了,程序崩溃了at prog.cpp:7,就行了return Well.back();.
(gdb) run
Starting program: /home/linux/t/prog
4*(3+2)
4
Program received signal SIGSEGV, Segmentation fault.
0x08048d0b in DishWell::ReturnEnd (this=0xbffff460) at prog.cpp:7
7 return Well.back();
Run Code Online (Sandbox Code Playgroud)
对于更复杂的程序,您通常需要列出当前正在调用的所有函数.您可以使用bt"回溯"的缩写获取该信息.在下面的回溯中,您会看到函数main(#1)正在调用函数DishWell::ReturnEnd(#0).#0是当前函数,因为函数形成堆栈,其中当前函数是堆栈的顶部(偏移量0是顶部).
(gdb) bt
#0 0x08048d0b in DishWell::ReturnEnd (this=0xbffff460) at prog.cpp:7
#1 0x08048b35 in main (argc=1, argv=0xbffff534) at prog.cpp:75
(gdb)
Run Code Online (Sandbox Code Playgroud)
只有这两个命令(run,bt),您已经解决了80%的问题:找到程序崩溃的位置.如果您在这里停止阅读,您应该能够通过添加print语句或断言来解决问题,以查看状态Well是什么以及为什么back()崩溃您的程序.但是让我们再使用gdb一些......
您可以键入list以查看该行周围的源代码,以获得更多上下文,而无需离开调试器.
(gdb) list
2 using namespace std;
3
4 class DishWell{
5 public:
6 char ReturnEnd(){
7 return Well.back();
8 }
9 void Push(char x){
10 Well.push_back(x);
11 }
(gdb)
Run Code Online (Sandbox Code Playgroud)
gdb可以打印变量和简单表达式.打印Well这里的值对新手来说没什么用处,因为它是一个复杂的数据结构,而不是一个简单的变量.但我们可以告诉gdb在该变量上调用一个方法......
(gdb) print Well.size()
$2 = 0
(gdb) print Well.empty()
$3 = true
Run Code Online (Sandbox Code Playgroud)
啊哈,Well是空的,你已经打电话back()了.当我们查看一些好的文档时std::vector,我们会看到您调用未定义的行为,在这种情况下是程序崩溃.
现在看看你的程序,并尝试找出Well当你的程序不期望它是空的时候为什么是空的.如果您愿意gdb,可以阅读一些教程并学习如何设置断点或单步.