c++ - C++ 编程语言练习第 3 版 - 桌面计算器

标签 c++

我不确定 Bjarne 对这个练习的意义:

“将桌面计算器转换为使用符号结构,而不是使用静态变量 number_value 和 string_value。”

他的意思是将这 2 个变量放在结构中,然后通过结构使用它们吗?

编辑:还有一个与 clculator 相关的练习,它说: “允许用户在 claculator 中定义函数。提示:将函数定义为操作序列,就像用户输入它们一样。这样的序列可以存储为 char 字符串或标记列表。然后阅读并在函数被调用时执行这些操作。如果您希望用户定义的函数接受参数,则必须为此发明一种表示法。”

谁能举例说明它的意思? 用户应该定义什么样的功能,我不明白。例如,能够定义从其参数返回 ^2 值的函数吗?

这是代码。

#include <iostream>
#include <map>

using namespace std;

double term(bool);
double expr(bool);
double prim(bool);
double error(const string&);

double number_value;
string string_value;

int no_of_errors;
map<string, double> table;

enum Token_value {
     NAME,          NUMBER,          END,
     PLUS = '+',    MINUS = '-',     MUL = '*',    DIV = '/',
     PRINT = ';',   ASSIGN = '=',    LP = '(',     RP = ')'
};

Token_value curr_tok = PRINT;
Token_value get_token();

double expr(bool get)
{
       double left = term(get);

       for(;;)
           switch(curr_tok) {
               case PLUS:
                    left += term(true);
                    break;
               case MINUS:
                    left -= term(true);
                    break;
               default:
                       return left;
           }
}

double term(bool get)
{
       double left = prim(get);

       for(;;) 
           switch(curr_tok) {
              case MUL:
                   left *= prim(true);
                   break;
              case DIV:
                   if(double d = prim(true)) {
                       left /= d;
                       break;
                   }
                   return error("divide by zero");
              default:
                      return left;
           }
}

double prim(bool get)
{
       if(get)
          get_token();

       switch(curr_tok) {
           case NUMBER: {
                double v = number_value;
                get_token();
                return v;
           }
           case NAME: {
                double &v = table[string_value];
                if(get_token() == ASSIGN)
                   v = expr(true);
                return v;
           }
           case MINUS:
                return -prim(true);
           case LP: {
                double e = expr(true);
                if(curr_tok != RP)
                  return error(") expected");
                get_token();
                return e;
           }
           default:
                   return error("primary expected");
       }
}

Token_value get_token()
{
       char ch = 0;
       do {
           if(!cin.get(ch)) 
              return curr_tok = END;
       } while(ch != '\n' && isspace(ch));

       switch(ch) {
           case 0:
                return curr_tok = END;
           case ';':
           case '\n':
                return curr_tok = PRINT;
           case '+':
           case '-':
           case '/':
           case '*':
           case '(':
           case ')':
           case '=':
                return curr_tok = Token_value(ch);
           case '0': case '1': case '2': case '3':
           case '4': case '5': case '6': case '7':
           case '8': case '9': case '.':
                cin.putback(ch);
                cin >> number_value;
                return curr_tok = NUMBER;
           default:
                   if(isalpha(ch)) {
                       string_value = ch;
                       while(cin.get(ch) && isalnum(ch))
                          string_value.push_back(ch);
                       cin.putback(ch);
                       return curr_tok = NAME;
                   }
                   error("bad token");
                   return curr_tok = PRINT;
       }
}

double error(const string &s)
{
       no_of_errors++;
       cerr << "error: " << s << '\n';
       return 1;
}

int main()
{
      table["pi"] = 3.14;
      table["e"] = 2.71;

      while(cin) {
          get_token();
          if(curr_tok == END)
             break;
          if(curr_tok == PRINT)
             continue;
          cout << expr(false) << endl;
      }
      return no_of_errors;
}

最佳答案

在我看来,这正是他的意思。此外,该结构也不应该是全局的,它应该作为参数传递(按值或适本地引用)。

关于c++ - C++ 编程语言练习第 3 版 - 桌面计算器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3314121/

相关文章:

c++ - Qt 中的 MS Word/ODF 自动化

c++ - 将指针数组初始化为空指针

c++ - 英特尔TBB并发队列如何工作?它是否实现了细粒度的并行性?

c++ - 为什么我会收到错误 'vector iterators incompatible' ?

c++ - 是否建议在函数中使用 using 关键字?

c++ - Windows 上的代码覆盖率与专有测试自动化

c++ - cvScalar 的顺序

c++ - 将库导入到我的 C++ 项目时出现问题,如何解决此问题?

c++ - 使用 flex/yacc 编写 C++ 编译器需要多少时间?

c++ - OpenGL:如何自动选择正确的 mipmap 方法?