65.9K
CodeProject 正在变化。 阅读更多。
Home

简单的可扩展 RPN 计算器类

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.64/5 (8投票s)

2003 年 10 月 20 日

3分钟阅读

viewsIcon

51027

downloadIcon

1547

本文介绍一个简单但易于扩展的类,该类允许执行算术计算。

Sample Image - calctest.jpg

引言

本文介绍一个简单但可扩展的 C++ 类,用于执行算术计算。当您需要计算编译时未知的表达式时,可以使用它。我猜它的主要用途是用于计算器程序,然后 - 无论您认为它有什么用处。

这些计算基于一百年前发明的逆波兰表示法技术 - 这是最容易实现的。您可以在 http://www.calculator.org/rpn.html 找到更多关于 RPN 的信息

如何使用

要使用该类,您只需在您的项目中包含一个“calctypes.h”,并在您想要它的地方创建一个该类的对象。 演示项目是用 WTL 7.0 编写的,并且源代码依赖于 WTL 的 CString(位于“atlmisc.h”中),这通常来说是一个严重的缺陷。您可以看看是否可以轻松地将其替换为 MFC CString,或者可能只是一个 char*

然后,当您需要计算某些内容时,只需调用 Calculate(LPSTR, LPSTR) 函数,其中表达式作为第一个参数,变量列表作为第二个参数。 它将返回计算出的值。

expression 应该只包含数字、运算符和变量(我认为是除了前两者之外的所有内容)。 数字由 '0' 到 '9' 和一个 '.' 组成,运算符标签在“calctypes.h”中配置。 您应该自己尝试一下,我总是使用“x”和“y”等名称作为变量。 例如 "Sin(x+y-Pow(2 +Cos(x-y),x*y))"。 请注意,我将括号视为运算符。

variablelist 是以分号分隔的等式列表,例如 "x=12;y=31;z=2.3323",并且不应有尾随分号。

如何扩展它

calctypes.cpp”中只定义了数量有限的简单运算符,您可能想添加一些符合您口味的东西。 我在编写这个类的所有努力都是为了使实现新的运算符变得容易。 您可以使用此类创建像“Indicator”或“Magnitude”或“Gradient”之类的运算符。 通过对类进行稍微修改,您甚至可以实现不同的运算符集,这些运算符可以在计算表达式时使用。 限制是所有运算符的参数都不应超过 3 个。 如果有人知道一种先进的技术可以用来在我的类中实现“n”个参数运算符,请告诉我。

现在直接切入正题。计算表达式的代码不以任何方式依赖于定义的运算符。 您应该执行以下操作以将新的算术运算符添加到计算器类

步骤

  1. 定义一个函数,该函数接受 3 个指向双精度数的指针并返回一个双精度数。

    它应该符合以下 typedef

    typedef double (*TThreeArgFnPtr) (double * in_pdArg1,
        double* in_pdArg2 = NULL,double* in_pdArg3 = NULL);

    您应该将其放在“calctypes.cpp”文件中,它应该看起来像这样

    double Addition(double * in_pdArg1,double* in_pdArg2 = NULL,
        double* in_pdDummy = NULL) 
    {
        return *in_pdArg1 + *in_pdArg2;
    }
  2. 然后,为您新添加的运算符创建一个结构体 SOperator全局对象。

    该结构的构造函数接受 4 个参数 - 第一个是运算符标签,这是一个字符串,用于标识表达式中的运算符,第二个是它的优先级,第三个是运算符参数的数量,最后一个是应该用于计算的函数(您刚刚添加的)。

    您最终应该得到类似这样的东西

    SOperator AdditionOperator(_T("+"),1,2,Addition);

    一旦完成,您需要在运算符数组中放置一个指向新声明的运算符的指针,该数组是

    SOperator* g_aUsualOperators[g_constNumberOfOperators] = ...

    最后要做的是修改在“calctypes.h”中声明的 g_constNumberOfOperators 变量

你完成了。 我告诉过你这很容易 :) 随意使用它,不要犹豫发送反馈。 甚至是批评。 :)

待办事项

然而,关于它有一些真正糟糕的事情

  1. 代码有缺陷。 抱歉没有时间润色它。
  2. 运算符不能接受超过 3 个参数。 有人知道方法吗?
  3. 运算符集尚未实现。
  4. 依赖于 CString
  5. 你说什么? :)
基于 RPN 的简单可扩展计算器类 - CodeProject - 代码之家
© . All rights reserved.