基于C++计算器,中序表达式,后序表达式,波兰表达式

要求

  1. 采用多个头文件、多个实现文件的方式实现完整程序(使得源代码的物理结构和逻辑结构保持一致);
  2. 输入中每遇到一个分号或回车(‘\n’)就认为一个完整表达式结束,并将该完整表达式记作一行。在处理过程中累计行数(和行号);
  3. 对于输入中存在的错误,除了提示错误现象外,还需提示相应的出错行号(即表达式的序号)。
  4. 必须支持命令行参数,以指明从何处读取所有表达式。
  • 命令行参数中的第2项开始,指定0~多个输入文件之路径。输入文件就是普通的文本文件,其中预先输入了若干表达式,内容及格式 均与来自标准输入的完全相同。
  • 若命令行参数未指明输入文件,则程序从标准输入设备(cin)读取表达式。
  • 若命令行指明了1~N个输入文件,则程序依次从这些文件读入表达式,并按照读到的顺序依次处理他们。

代码文件说明

每一个类都由头文件和源文件组成。

calch.h文件

#pragma once#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #include "calc.h"
#include "datahandler.h"
#include "eval.h"
#include "lexer.h"
#include "sym.h"
#include "filenotfound.h"
#include "illegalname.h"
#include "evalerror.h"

我把所有的头文件在这个文件中一次引用,之后后面的代码每一个头文件都要引用这个头文件。

主函数文件

#include "calch.h"using namespace std;
using namespace calculator;int main(int argc, char* argv[])
{calc mycalc(argc, argv);system("pause");return 0;
}

calc

头文件

#pragma once#include "calch.h"namespace calculator
{class calc{public:calc(int argc, char * argv[]);};
}

源文件

#include "calc.h"using namespace calculator;
using namespace std;datahandler dh;
sym symbol_table;calc::calc(int argc, char* argv[])
{try{dh.init(argc, argv);}catch (filenotfound e){cout << e.what() << endl;}vector<string> lines = dh.getLines();int pos = 1;for (vector<string>::iterator it = lines.begin(); it < lines.end(); ++it){laxer mylaxer(*it, pos);try{mylaxer.getcalc();}catch (evalerror e){cout << e.what() << endl;}catch (illegalname e){cout << e.what() << endl;}++pos;}
}

datahandler

头文件

#pragma once#include "calch.h"namespace calculator
{class datahandler{public:~datahandler();void init(int argc, char * argv[]);void handlekeybordinput();void handlefileinput();void handlechar(char c);void output2keybord();std::vector<std::string> getLines();private:std::vector<std::string> lines;std::ifstream infile;std::string tempstr;};
}

源文件

#include "datahandler.h"using namespace std;
using namespace calculator;datahandler::~datahandler()
{std::vector<std::string>().swap(lines);tempstr.clear();infile.close();
}void datahandler::init(int argc, char * argv[])
{if (argc == 1)handlekeybordinput();else{string filename;for (int i = 1; i < argc; i++){filename = argv[i];infile.open(filename);if (!infile.is_open())throw filenotfound(filename);elsehandlefileinput();}}
}void datahandler::handlekeybordinput()
{cin >> noskipws;char c;while (cin >> c)handlechar(c);
}void datahandler::handlefileinput()
{char c;infile >> noskipws;int pos = 0;while (!infile.eof()){infile >> c;handlechar(c);}	
}void datahandler::handlechar(char c)
{switch (c){case ' ':break;case ';':if (tempstr.empty())break;tempstr.append(1, c);lines.push_back(this->tempstr);tempstr.clear();break;case '\n':if (tempstr.empty())break;lines.push_back(this->tempstr);tempstr.clear();break;default:tempstr.append(1, c);break;}	
}void datahandler::output2keybord()
{int pos = 1;for (vector<string>::iterator it = lines.begin(); it < lines.end(); ++it){cout << pos << "\t" << (*it) << endl;++pos;}
}vector<std::string> datahandler::getLines()
{return lines;
}

eval

头文件

#pragma once#include "calch.h"namespace calculator
{class eval{typedef struct Reverse_Polish_Expression{Reverse_Polish_Expression(double num){data.num = num;this->symbol = true;}Reverse_Polish_Expression(char ch){data.op = ch;this->symbol = false;}union data{double num = 0.0;char op;}data;bool symbol;}RPE;public:eval();~eval();double calc(std::string line);double itercalc(std::string::iterator & begin, std::string::iterator & end);void parenthesis_matching(std::string str);void ophandler(char op, std::stack<char>& opStack, std::stack<RPE>& num);bool isNumber(char ch);bool ispartofNumber(char ch);bool isOperator(char ch);bool isLetter(char ch);void symbolhandler(std::string::iterator & it, std::stack<RPE> & num);void tranNum(std::string::iterator & it, std::stack<RPE>& num);void residueOphandler(std::stack<char>& opStack, std::stack<RPE>& number);void reverseStack(std::stack<RPE>& number);double RPEhandler(std::stack<RPE>& number);private:std::string line;std::map<char, int> priority;std::set<char> op;};
}

源文件

#include "eval.h"using namespace std;
using namespace calculator;extern sym symbol_table;eval::eval()
{priority['+'] = 1;priority['-'] = 1;priority['*'] = 2;priority['/'] = 2;priority['^'] = 3;op.insert('+');op.insert('-');op.insert('*');op.insert('/');op.insert('^');
}eval::~eval()
{line.clear();priority.clear();op.clear();
}double eval::calc(string line)
{if (*(line.end() - 1) == ';')this->line = line.substr(0, line.length() - 1);elsethis->line = line;parenthesis_matching(this->line);string::iterator itbegin = this->line.begin();string::iterator itend = this->line.end();return itercalc(itbegin, itend);
}double eval::itercalc(string::iterator &begin, string::iterator &end)
{stack<RPE> num;stack<char> opStack;bool lasttoken = true;for (; begin < end; ++begin){if (*begin == '('){int n = 1;++begin;string::iterator nextbegin = begin;for (; begin < end; ++begin)if (*begin == ')'){--n;if (n == 0){num.push(RPE(itercalc(nextbegin, begin)));break;}}else if (*begin == '('){++n;}lasttoken = false;if (begin >= end)break;}if (lasttoken && ispartofNumber(*begin)){tranNum(begin, num);lasttoken = false;}else{if (isOperator(*begin)){if (lasttoken)throw "Operator error.";ophandler(*begin, opStack, num);lasttoken = true;}else if (isLetter(*begin)){symbolhandler(begin, num);lasttoken = false;}else if (*begin == ')')continue;elsethrow "Unknown operation.";}}if (lasttoken)throw "Operator error.";residueOphandler(opStack, num);reverseStack(num);return RPEhandler(num);
}void eval::parenthesis_matching(string str)
{int n = 0;for (string::iterator it = str.begin(); it < str.end(); ++it){if (*it == '(')++n;if (*it == ')'){if (n > 0)--n;elsethrow "Parenthesis unmatching.";}}if (n != 0)throw "Parenthesis unmatching.";
}void eval::ophandler(char op, stack<char> &opStack, stack<RPE> &num)
{while (!opStack.empty() && priority[op] <= priority[opStack.top()]){num.push(RPE(opStack.top()));opStack.pop();}opStack.push(op);
}void eval::symbolhandler(string::iterator &it, stack<RPE> &num)
{string tempstr;tempstr.append(1, *it);for (++it; it < line.end(); ++it)if (isLetter(*it) || isNumber(*it))tempstr.append(1, *it);elsebreak;try{num.push(RPE(symbol_table.find(tempstr)));}catch (const char* str){throw str;}--it;
}void eval::tranNum(string::iterator &it, stack<RPE> &num)
{string tempstr;double n;if (ispartofNumber(*it))tempstr.append(1, *it);++it;for (; it < line.end(); ++it)if (isNumber(*it) || *it == '.')tempstr.append(1, *it);elsebreak;if (!isNumber(tempstr[0]) && tempstr[0] != '-')throw "Operator error.";stringstream ss(tempstr);ss >> n;num.push(RPE(n));--it;
}void eval::residueOphandler(stack<char> &opStack, stack<RPE> &number)
{while (!opStack.empty()){number.push(RPE(opStack.top()));opStack.pop();}
}void eval::reverseStack(stack<RPE> &number)
{queue<RPE> queue;while (!number.empty()){queue.push(number.top());number.pop();}while (!queue.empty()){number.push(queue.front());queue.pop();}
}double eval::RPEhandler(stack<RPE> &number)
{stack<double> result;char tempOp;double tempnum1, tempnum2;while (!number.empty()){if (number.top().symbol){result.push(number.top().data.num);number.pop();}else{tempOp = number.top().data.op;number.pop();if (result.size() < 2)throw "Operator error.";tempnum2 = result.top();result.pop();tempnum1 = result.top();result.pop();switch (tempOp){case '+':result.push(tempnum1 + tempnum2);break;case '-':result.push(tempnum1 - tempnum2);break;case '*':result.push(tempnum1 * tempnum2);break;case '/':result.push(tempnum1 / tempnum2);break;case '^':result.push(pow(tempnum1, tempnum2));break;default:throw "Operator error.";}}}if (!number.empty())throw "Operator error.";if (isinf(result.top()) || isnan(result.top()))throw "Divide 0 is not allow.";if (result.size() != 1)throw "Number error.";return result.top();
}bool eval::isNumber(char ch)
{return ch >= '0' && ch <= '9';
}bool eval::ispartofNumber(char ch)
{return isNumber(ch) || ch == '.' || ch == '-' || ch == '+';
}bool eval::isOperator(char ch)
{return op.count(ch) != 0;
}bool eval::isLetter(char ch)
{return ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'));
}

evalerror

头文件

#pragma once#include "calch.h"namespace calculator
{class evalerror{public:evalerror(std::string except, int Line);~evalerror();std::string what();private:std::string except;};
}

源文件

#include "evalerror.h"using namespace std;
using namespace calculator;evalerror::evalerror(string except, int Line)
{this->except = "EVALERROR ERROR: " + except + " Line " + to_string(Line);
}evalerror::~evalerror()
{except.clear();
}string evalerror::what()
{return except;
}

filenotfound

头文件

#pragma once#include "calch.h"namespace calculator
{class filenotfound{public:filenotfound(std::string except);~filenotfound();std::string what();private:std::string except;};
}

源文件

#include "filenotfound.h"using namespace calculator;
using namespace std;filenotfound::filenotfound(string except)
{this->except = "FILENOTFOUND ERROR: " + except;
}filenotfound::~filenotfound()
{except.clear();
}string filenotfound::what()
{return except;
}

illegalname

头文件

namespace calculator
{class illegalname{public:illegalname(std::string except, int Line);~illegalname();std::string what();private:std::string except;};
}

源文件

#include "illegalname.h"using namespace std;
using namespace calculator;illegalname::illegalname(string except, int Line)
{this->except = "ILLEGALNAME ERROR: " + except + " Line " + to_string(Line);
}illegalname::~illegalname()
{except.clear();
}string illegalname::what()
{return except;
}

lexer

头文件

namespace calculator
{class lexer{enum ChooseSymbol{num, symbol, token};public:lexer(std::string line, int Lnum);~lexer();void getcalc();void symbolhandle(std::string str);bool isLetter(const char ch);bool isNumber(const char ch);private:int Lnum;double ans;std::vector<std::string> s;std::string line;enum ChooseSymbol cs;};
}

源文件

#include "lexer.h"using namespace calculator;
using namespace std;extern sym symbol_table;
eval myeval;lexer::lexer(string line, int Lnum)
{this->line = line;this->Lnum = Lnum;
}lexer::~lexer()
{s.clear();line.clear();
}void lexer::getcalc()
{int equalpos = line.find("=");bool flag = *(line.end() - 1) == ';';if (equalpos > -1){try{ans = myeval.calc(line.substr(equalpos + 1));}catch (const char* str){throw evalerror(str, Lnum);}try{symbolhandle(line.substr(0, equalpos));}catch (const char* str){throw illegalname(str, Lnum);}if (!flag)cout << line.substr(0, equalpos) << " = " << ans << endl;}else{try{if (flag)ans = myeval.calc(line.substr(0, line.length() - 1));elseans = myeval.calc(line);}catch (const char* str){throw evalerror(str, Lnum);}symbol_table.add("ans", ans);if (!flag)cout << "ans = " << ans << endl;}
}void lexer::symbolhandle(string str)
{string tempsym;string::iterator it = str.begin();if (!isLetter(*it))throw "Not conform to the standard.";for (; it < str.end(); ++it)if (!(isLetter(*it) || isNumber(*it)))throw "Not conform to the standard.";elsetempsym.append(1, *it);symbol_table.add(tempsym, ans);
}bool lexer::isLetter(const char ch)
{return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}bool lexer::isNumber(const char ch)
{return (ch >= '0' && ch <= '9');
}

sym

头文件

#pragma once#include "calch.h"namespace calculator
{class sym{public:sym();~sym();void add(std::string symbol, double num);double find(std::string symbol);private:std::map<std::string, double>table;};
}

源文件

#include "sym.h"using namespace calculator;sym::sym()
{table["e"] = 2.71828182845904523536;table["pi"] = 3.14159265358979323846;
}sym::~sym()
{table.clear();
}void sym::add(std::string symbol, double num)
{table[symbol] = num;
}double sym::find(std::string symbol)
{if (table.count(symbol) == 0)throw "No such symbol.";return table[symbol];
}

代码说明

数据结构:eval.h中定义了逆波兰表达式所需的节点,其中包含一个联合体data与symbol,data为了表示数据,symbol用于区分数字与符号。

typedef struct Reverse_Polish_Expression
{Reverse_Polish_Expression(double num){data.num = num;this->symbol = true;}Reverse_Polish_Expression(char ch){data.op = ch;this->symbol = false;}union data{double num = 0.0;char op;}data;bool symbol;
}RPE;

算法1 int main()
作 用:主控函数,也实现对题目所需其他内容的测试。
参 数:int argc, char* argv[]:命令行参数
返回值:总是返回0。
计算过程:
创建calc类,名为mycalc。

类1 calc类
算法1.1 构造器calc::calc()
作 用:构造计算器,处理各类跑出的异常。
参 数:int argc, char* argv[]:命令行参数
返回值:无
计算过程:
(1) try/catch语句,调用数据处理类,该类调用算法2.1,处理filenotfound错误。
(2) 调用数据处理类,该类调用算法2.2,返回值赋值给lines。
(3) 循环遍历lines,读取lines中每一元素。
(4) try/catch语句,将lines中元素给语法分析类,该类调用算法3.2,处理evalerror与illegalname错误。

类2 datahandler类
算法2.1 void datahandler::init(int argc, char * argv[])
作 用:初始化状态,判断数据来源。
参 数:int argc, char * argv[]:命令行参数
返回值:无
计算过程:
(1) 判断argc为1,调用算法2.3。
(2) 判断argc不为1,循环遍历argv,将其当做文件名处理,如果文件找不到,抛出异常filenotfound;否则调用算法2.4。

算法2.2 vectorstd::string datahandler::getLines()
作 用:返回私有成员lines
参 数:无
返回值:lines
计算过程:
返回私有成员lines。

算法2.3 void datahandler::handlekeybordinput()
作 用:处理键盘输入
参 数:无
返回值:无
计算过程:
(1) 将cin模式调为不跳过结束符。
(2) 每次读入一个字符,并调用算法2.5。

算法2.4 void datahandler::handlefileinput()
作 用:处理文件输入
参 数:无
返回值:无
计算过程:
(1) 将文件内容按字符输入,不调过结束符。
(2) 每次读入一个字符,并调用算法2.5。

算法2.5 void datahandler::handlechar(char c)
作 用:处理一个字符
参 数:char c:传入字符
返回值:无
计算过程:
(1) 如果c是空格就退出。
(2) 如果c是‘;’,如果tempstr为空,则退出;否则,就将其接在tempstr后面,之后在lines中加入tempstr。
(3) 如果c是‘\n’,如果tempstr为空,则退出;否则,在lines中加入tempstr。
(4) 如果c都不满足上述条件,就将其接在tempstr后面。

类3 laxer类
算法3.1 构造器laxer::laxer(string line, int Lnum)
作 用:为成员变量赋值
参 数:
string line:一行
int Lnum:行号
返回值:无
计算过程:
为成员变量赋值

算法3.2 void laxer::getcalc()
作 用:进行语法分析
参 数:无
返回值:无
计算过程:
(1) 找到成员变量line中的‘=’,以此作为分隔,前面为新增符号,后面为表达式。
(2) 判断语句结尾是否有‘;’,有则为真,将结果赋值给flag。
(3) 判断‘=’位置,如果有,则调用算法4.2计算表达式的值并赋值给ans,并处理异常,之后调用算法3.3,处理赋值;如果没有,则调用算法4.2计算表达式的值并赋值给ans,并处理异常,之后将值放入符号表中ans项。
(4) 判断flag,如果为真,输出结果,符号为自定义符号,如果为假,则输出符号ans的值。

算法3.3 void laxer::symbolhandle(string str)
作 用:处理符号,检查是否为不符合规定的符号。
参 数:string str:符号
返回值:无
计算过程:
(1) 先检查符号的第一位,不为字母,则抛出异常。
(2) 后面如果出现不为字母或数字的字符,则抛出异常。
(3) 如果符合标准,则将该符号加入符号表,并将赋值为ans的值。

算法3.4 bool laxer::isLetter(const char ch)
作 用:判断是否为字母
参 数:const char ch:传入字符
返回值:(ch >= ‘a’ && ch <= ‘z’) || (ch >= ‘A’ && ch <= ‘Z’)
计算过程:
判断传入字符是否为字母。

算法3.5 bool laxer::isNumber(const char ch)
作 用:判断是否为数字
参 数:const char ch:传入字符
返回值:(ch >= ‘0’ && ch <= ‘9’)
计算过程:
判断传入字符是否为数字。

类4 eval类
算法4.1 构造器eval::eval()
作 用:初始化成员变量
参 数:无
返回值:无
计算过程:
初始化成员变量,为各个运算符分配优先级。

算法4.2 double eval::calc(string line)
作 用:计算表达式值,将表达式看做由很多括号括起来的子式,之后迭代计算。
参 数:string line:表达式
返回值:表达式的值
计算过程:
(1) 判断表达式后是否有‘;’,有就去掉。
(2) 调用算法4.3,检查括号是否匹配。
(3) 调用算法4.4。

算法4.3 void eval::parenthesis_matching(string str)
作 用:判断括号是否匹配
参 数:string str:表达式
返回值:无
计算过程:
(1) 使用一个整数n。
(2) 每次遇到‘(’,n就累加1,每次遇到‘)’,判断是否小于0,是就抛出异常,不是n就减1。
(3) 结束循环后,检查n是否为0,不是就抛出异常。

算法4.4 double eval::itercalc(string::iterator &begin, string::iterator &end)
作 用:计算一个算术子式,即计算一个无括号算式。
参 数:string::iterator &begin:算术子式的开头
string::iterator &end:算术子式的结尾
返回值:算术子式的值
计算过程:
使用逆波兰表达式计算算术子式。
(1) 使用栈,第一个栈为运算符栈,其中使用结构为结构体RPE,第二个栈为操作符栈。
(2) 扫描整个字符串,读入为数字或者符号,则压入运算符栈,读入为操作符,则按照逆波兰表达式的规则压入运算符栈或者操作符栈,这里运算符栈结构为结构体RPE,使用symbol来区分是操作符还是数字。
(3) 在扫描过程中,发现‘(’,则把这个括号当做起始位置,向后找到与之对应的‘)’,之后将其中的式子当做子式,调用算法4.4,进行下一轮循环,将迭代结果压入运算符栈中。
(4) 最外层的迭代返回整个式子的结果。

算法4.5 void eval::ophandler(char op, stack &opStack, stack &num)
作 用:处理操作符
参 数:
char op:操作符
stack &opStack:操作符栈
stack &num:运算符栈
返回值:无
计算过程:
解决逆波兰表达式中运算符优先级问题。

算法4.6 void eval::symbolhandler(string::iterator &it, stack &num)
作 用:处理符号
参 数:
string::iterator &it:符号在字符串中出现的开始位置
stack &num:运算符栈
返回值:无
计算过程:
检测符号,将符号转换为数字并压入运算符栈,没有该运算符则抛出异常。

算法4.7 void eval::tranNum(string::iterator &it, stack &num)
作 用:处理数字
参 数:
string::iterator &it:数字在字符串中出现位置
stack &num:运算符栈
返回值:无
计算过程:
检测数字,将字符串转换为数字并压入运算符栈。

算法4.8 void eval::residueOphandler(stack &opStack, stack &number)
作 用:将操作符栈剩余的操作符压入运算符栈
参 数:
stack &opStack:操作符栈
stack &number:运算符栈
返回值:无
计算过程:
将操作符栈剩余的操作符压入运算符栈

算法4.9 void eval::reverseStack(stack &number)
作 用:翻转运算符栈
参 数:
stack &number:运算符栈
返回值:无
计算过程:
用队列将运算符栈翻转

算法4.10 double eval::RPEhandler(stack &number)
作 用:处理逆波兰表达式
参 数:
stack &number:运算符栈
返回值:逆波兰表达式计算结果
计算过程:
(1) 建立一个结果栈,从运算符栈中弹出项,如果为数字,则直接压入结果栈,如果是符号,则从结果栈中弹出两个数字,进行运算后压入结果栈中。
(2) 判断操作数栈是否为空,不为空抛出异常。
(3) 判断结果栈栈顶是否为inf,是则抛出异常。
(4) 判断结果栈大小是否为1,不是则抛出异常。
(5) 返回结果栈顶。

算法4.11 bool eval::isNumber(char ch)
作 用:判断是否为数字,
参 数:
char ch:输入字符,
返回值:true则为是,false则为否,
计算过程:
判断是否为数字,

算法4.12 bool eval::ispartofNumber(char ch)
作 用:判断是否为一个数字的一部分,
参 数:
char ch:输入字符,
返回值:true则为是,false则为否,
计算过程:
判断是否为一个数字的一部分,

算法4.13 bool eval::isOperator(char ch)
作 用:判断是否为操作符,
参 数:
char ch:输入字符,
返回值:true则为是,false则为否,
计算过程:
判断是否为操作符,

算法4.14 bool eval::isLetter(char ch)
作 用:判断是否为字母。
参 数:
char ch:输入字符。
返回值:true则为是,false则为否。
计算过程:
判断是否为字母。

类5 sym类
算法5.1 构造器sym::sym()
作 用:初始化符号表。
参 数:无
返回值:无
计算过程:
初始化符号表。

算法5.2 void sym::add(std::string symbol, double num)
作 用:向符号表中添加元素。
参 数:
std::string symbol:符号。
double num:符号的值。
返回值:无
计算过程:
在符号表中插入键为symbol,值为num的项。

算法5.3 double sym::find(std::string symbol)
作 用:在符号表里查找一个元素。
参 数:
std::string symbol:需要查找的元素的键值。
返回值:键的值
计算过程:
先查找是否有该元素,如果没有就抛出异常,有就返回键的值。

类6 evalerror类
算法6.1 构造器evalerror::evalerror(string except, int Line)
作 用:初始化类
参 数:
string except:抛出异常的内容。
int Line:行号。
返回值:无
计算过程:
初始化成员

算法6.2 string evalerror::what()
作 用:返回错误内容。
参 数:无
返回值:错误内容
计算过程:
返回错误内容。

类7 filenotfound类
算法7.1 构造器filenotfound::filenotfound(string except)
作 用:初始化类
参 数:
string except:抛出异常的内容。
int Line:行号。
返回值:无
计算过程:
初始化成员

算法7.2 string filenotfound::what()
作 用:返回错误内容。
参 数:无
返回值:错误内容
计算过程:
返回错误内容。

类8 illegalname类
算法8.1 构造器illegalname::illegalname(string except, int Line)
作 用:初始化类
参 数:
string except:抛出异常的内容。
int Line:行号。
返回值:无
计算过程:
初始化成员

算法8.2 string illegalname::what()
作 用:返回错误内容。
参 数:无
返回值:错误内容
计算过程:
返回错误内容。

测试结果

输入1

b=7
c=21
a=3
a^2
A^2
9abc=5+6;
9/0
1/0-1/0
a*(2+3)
^1+1
1**2
1&+2
1(2+3*)
^Z

输出1

b = 7
c = 21
a = 3
ans = 9
EVALERROR ERROR: No such symbol. Line 5
ILLEGALNAME ERROR: Not conform to the standard. Line 6
EVALERROR ERROR: Divide 0 is not allow. Line 7
EVALERROR ERROR: Divide 0 is not allow. Line 8
ans = 15
EVALERROR ERROR: Operator error. Line 10
EVALERROR ERROR: Operator error. Line 11
EVALERROR ERROR: Unknown operation. Line 12
EVALERROR ERROR: Operator error. Line 13

输入2

a=4;b=3;c=a+b;d=haha
a
b
c
^Z

输出2

EVALERROR ERROR: No such symbol. Line 4
ans = 4
ans = 3
ans = 7


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部