C++计算器的实现 (可以拓展)

思路:

1:从字符串中获取中缀表达式 

2:中缀表达式转换为后缀表达式

3:用后缀表达式计算结果

总体:

定义一个计算器处理类 作为对外唯一接口 class Calc_tag

获取计算的字符串  void WhatToCalc(const char *str);

计算  double Calc();

具体:

定义一个结构 保存 符号和数值

struct My_Token_tag
{
    int type;      //类型 1为数字 ,2为符号,3为函数
    union 
    {
        double value;  // 数字的值
        Sig_tag *sig;   //符号或函数
    };
};

其中Sig_tag为

typedef double (*My_Fun)(int n,double *p); 调用的函数类型
struct Sig_tag
{
    char sig[10];                // 符号的名字 如 +- sin cos 之类
    int prioriy;                 //优先级
    int pragmanum;                 //当前符号或函数的参数个数
    My_Fun fun;                //该符号或函数的调用操作 比如 + 调用+的函数f_plus
    Sig_tag():sig{0},prioriy(0),pragmanum(0),fun(0){}
    Sig_tag(const char *s1,int p1,int pp1,My_Fun fun1);
    Sig_tag operator = (Sig_tag s1);
     Sig_tag(const Sig_tag &s1);
     bool IsEmpty();
};

一些常用的函数 自己可以拓展补充
double f_plus(int n,double *p);
double f_dec(int n,double *p);
double f_mum(int n,double *p);
double f_div(int n,double*p);
double f_mod(int n,double*p);
double f_qf(int n,double *p);
double f_zs(int n,double *p);
//**********************************
double f_sqrt(int n,double *p);
double f_exp(int n,double *p);
double f_ln(int n,double *p);
double f_log(int n,double *p);
double f_sin(int n,double *p);
double f_cos(int n,double *p);
double f_tan(int n,double *p);
double f_atan2(int n,double *p);
double f_asin(int n,double *p);
double f_acos(int n,double *p);
double f_atan(int n,double *p);

 

具体操作:

class Calc_tag
{
    public:
        Calc_tag();
        ~Calc_tag();
        void WhatToCalc(const char *str);              要计算的表达式 不用“”=“ ”结束
        double Calc();                                对外计算
        void AddSig(Sig_tag sig1);          用于拓展
        void AddSig(const char *sig1,int p1,int pp1,My_Fun func1);  用于拓展
        void ToBackBDS();                转换为后缀表达式
        void PickTokens();                提取token ,匹配优先级 
        double RealCalc();                计算后缀表达式
        std::deque<My_Token_tag> & GetBDS() { return bds; }                      用于拓展
        std::deque<My_Token_tag> & GetBackBDS() { return tkbds; }        用于拓展
    private:
        std::vector<Sig_tag> basesig;            基本的符号库
        std::vector<Sig_tag> funcsions;       函数库可以拓展
        char *cacledstr;
        std::deque<My_Token_tag> bds;            表达式 token的队列
        std::deque<My_Token_tag>tkbds;      后缀表达式的队列
    protected:
        
        int IsBaseSig(Sig_tag & s1);            是否符号
        int IsBaseSig(const char *s1);
        int IsFuncSig(const char *s1);       是否是函数
        int IsFuncSig(Sig_tag &s1);
        Sig_tag GetBySig1(const char *pstr);    取得Sig_tag结构
        Sig_tag GetBySig2(const char *pstr);
    
        
};

要点:

处理 - 号 有歧义 什么时候是减 什么时候是负

对于函数的处理 (,) 分别该怎么执行

清理程序的申请内存避免内存泄漏

其他

资源里有两个工程文件 一个是LIB 还有个是测试

用VS2017 编辑的 里面的属性和 计算器库 位置要修改一下避免出错

 

上一篇:Linux 等待信号(sigsuspend)


下一篇:心理学统计之功效分析