17370845950

C++计算器怎么写 C++实现四则运算的简单代码【案例】
应使用双栈法解析四则运算表达式,而非std::stringstream或std::stod;维护nums和ops栈,按优先级计算,处理括号与负号,并严格校验输入合法性。

std::stringstreamstd::stod 解析表达式太危险

直接用字符串流或类型转换函数处理用户输入的四则运算表达式(比如 "3 + 4 * 2"),几乎必然出错。这些工具不理解运算符优先级,也不会递归解析括号,std::stod("3 + 4 * 2") 只会读到 3 就停,后面全被忽略。真要这么做,得自己拆分 token、建栈、模拟运算过程——相当于重写一个简易解释器。

推荐用双栈法实现中缀表达式求值(支持 + - * / 和括号)

这是教科书级解法,稳定、易懂、能覆盖常见需求。核心是维护两个栈:nums 存操作数,ops 存运算符。遇到数字就入 nums;遇到运算符时,先检查栈顶是否该立即计算(比如当前是 *,而栈顶是 +,那 + 不能等,得先算掉);遇到左括号无条件入栈,右括号则一路弹出直到左括号。

  • 优先级判断用 map:比如 {'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}
  • 注意负号处理:若 - 出现在开头或左括号后(如 "(-5 + 3)"),应视为一元负号,需补 0 入 nums
  • 除零必须检查:if (b == 0) throw std::runtime_error("division by zero");
double calc(double a, double b, char op) {
    switch(op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': if (b == 0) throw std::runtime_error("division by zero"); return a / b;
    }
    return 0;
}

别硬啃字符串解析,先用空格分隔再处理更稳妥

如果只要求用户输入带空格的格式(如 "3 + 4 *

2""10 / ( 2 - 1 )"),可以先用 std::istringstream 按空格切分 token,再逐个识别数字、运算符、括号。这样避免手写跳过空白、识别多位数、处理小数点等边界问题。

  • 读 token 时用 while (iss >> token)tokenstd::string
  • 判断 token == "("token == ")" 比判断单个字符更清晰
  • 数字用 std::stod(token) 安全转换,前提是已确认 token 不含非法字符

输入验证和错误恢复容易被忽略

真实场景下,用户可能输 "3++4""(5 + ""abc * 2"。只靠双栈逻辑无法捕获所有异常,必须在解析前/中加校验:

  • 扫描原始字符串,确保每个字符属于 0-9+-*/()、空格;小数点需成对出现在数字中
  • 左右括号数量必须相等,且过程中右括号不能多于左括号
  • 连续两个运算符(除一元负号外)非法,如 "3 * + 4"
  • 计算完成后,nums 应只剩 1 个数,ops 应为空,否则说明表达式不完整

这些检查点分散在词法分析和语法计算阶段,漏掉任意一个,程序就可能崩溃或返回错误结果。