0
我認爲是時候我完成了我一週前開始的小中綴計算器,並在我的評估函數中遇到了一個問題。我的switch語句似乎與我在操作符結構上處理數組的方式有關。我不完全確定我做錯了什麼。這不是我得到的唯一的錯誤,但我相信,如果我解決了這個問題,那麼其他問題應該更容易清理。很顯然,我的代碼不完整,但考慮到目前爲止,我在正確的軌道上?表達式必須有(指針)函數類型錯誤
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
bool die(const string &msg);
//stack class
class Stack{
public:
Stack();
void push(const double &val);
void push(const string &oper);
double popnum();
string popop();
double getopele();
double getnumele();
unsigned getarity(string token);
unsigned getprec(string token);
string topop();
private:
static const unsigned MAX=30;
string opstack[MAX];
double numstack[MAX];
unsigned opele;
unsigned numele;
};
//operators
bool add(double &r, double &x, double &y);
bool subtract(double &r, double &x, double &y);
bool multiply(double &r, double &x, double &y);
bool divide(double &r, double &x, double &y);
//operator type
struct OP{
string name;
void * func;
unsigned arity;
unsigned prec;
bool lass;
string descrip;
};
//operator table
OP op[]={{"+", add, 2, 4, true, "2+3 is 5"},
{"-", subtract, 2, 4, true, "2-3 is -1"},
{"*", multiply, 2, 6, true, "2*3 is 6"},
{"/", divide, 2, 6, true, "2/3 is 0.666666..., div by 0 illegal"}};
unsigned OPELE =sizeof(op)/sizeof(op[0]);
//Manip
unsigned findindex(string token);
bool parseval(double &t, const string &token);
double parseforeval(double &result, string line);
void evaluate(double &result, Stack &s);
bool weird(double x);
int main(){
for(string line; getline(cin, line);){
if(line=="QUIT") break;
if(line.empty()) continue;
if(line=="DOC")
for(unsigned i=0; i<OPELE; i++)
cout<<op[i].name<<" | "<<op[i].descrip<<'\n';
double result;
if(parseforeval(result, line)){
cout<<result<<'\n';
}else{
cout<<"Could not understand input\n\n";
}
}
}
Stack::Stack(){
opele=0;
numele=0;
}
void Stack::push(const double &val){
if(MAX) die("Stack Overflow");
numstack[numele++]=val;
}
void Stack::push(const string &oper){
if(MAX) die("Stack Overflow");
opstack[opele++]=oper;
}
double Stack::popnum(){
if(!numele) die("Stack Underflow");
return numstack[--numele];
}
string Stack::popop(){
if(!opele) die("Stack Underflow");
return opstack[--opele];
}
double Stack::getopele(){
return opele;
}
double Stack::getnumele(){
return numele;
}
unsigned Stack::getprec(string token){
unsigned i=findindex(token);
return op[i].prec;
}
unsigned Stack::getarity(string token){
unsigned i=findindex(token);
return op[i].arity;
}
string Stack::topop(){
if(!opele) die("Undeflow");
return opstack[opele-1];
}
double parsforeval(double &result, string line){
istringstream sin(line);
Stack s;
for(string token; sin>>token;){
double t;
if(parseval(t, token)){
s.push(t);
}else if(token=="("){
s.push(parsforeval(result, line));
}else if(s.getprec(s.topop()) >s.getprec(token)){
//write eval function
s.push(token);
}else if(token== ")"){
if(!s.getnumele()) die("Bad format");
return s.popnum();
}else{
s.push(token);
}
}
while(s.getopele()){
evaluate(result, s);
}
}
void evaluate(double &result, Stack &s){
unsigned i= findindex(s.popop());
switch(op[i].arity){
case 1:
if(s.getnumele()<1) die("Underflow");
double x = s.popnum();
if( !reinterpret_cast<bool (*)(double &, double &)> !op[i].func (result, x) ) die("No OP");
break;
case 2:
if(s.getnumele()<2) die("Underflow");
double y = s.popnum();
double x = s.popnum();
if( !reinterpret_cast<bool (*)(double &, double &,double &)> op[i].func (result, x, y) ) die("No OP");
break;
case 3:
if(s.getnumele()<3) die("Underflow");
double z = s.popnum();
double y = s.popnum();
double x = s.popnum();
if( !reinterpret_cast<bool (*)(double &, double & , double & , double &)>op[i].func (result, x, y, z) ) die("No OP");
break;
default:
die("uuuuuuhhhh i have no idea");
break;
}
s.push(result);
}
bool add(double &r, double &x, double &y){
double t = x + y;
if(weird(t)) return false;
r = t;
return true;
}
bool subtract(double &r, double &x, double &y){
double t = x - y;
if(weird(t)) return false;
r = t;
return true;
}
bool multiply(double & r, double& x, double &y){
double t = x * y;
if(weird(t)) return false;
r = t;
return true;
}
bool divide(double & result, double &x, double &y){
double t = x/y;
if(weird(t)) return false;
result = t;
return true;
}
unsigned findindex(string token){
for(unsigned i=0; i<OPELE; i++)
if(op[i].name==token)
return i;
return UINT_MAX;
}
bool parseval(double &val, const string &token){
istringstream sin(token);
double t;
if(!(sin >>t)) return false;
char junk;
if(sin >>junk) return false;
val = t;
return true;
}
bool weird(double x){
return x != x || x != 0 && x == 2*x;
}
bool die(const string &msg){
cout<<"Error: "<<msg;
exit(EXIT_FAILURE);
}
tl; dr哪條線出錯? – Barmar
在評估函數中,switch語句中的每個op實例都有該問題。 – Painguy
'reinterpret_cast'的參數應該在其周圍有括號。我認爲它可能會解析它,試圖重新解釋調用func而不是func成員iself的結果。 – Barmar