Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
如何用C++实现一个简单的计算器 控制台输入输出和基本运算处理_创想鸟

如何用C++实现一个简单的计算器 控制台输入输出和基本运算处理

计算器程序使用中缀表达式转后缀表达式的策略,并通过栈实现计算;其核心步骤为:1.定义运算符优先级函数precedence;2.实现中缀转后缀函数infixtopostfix,利用栈处理运算符并生成后缀队列;3.实现后缀表达式求值函数evaluatepostfix,用栈存储操作数并根据运算符执行计算;4.主函数main接收输入并调用上述函数,同时捕获和处理异常;5.空格处理依赖stringstream自动忽略并分割token;6.扩展新运算符需在precedence添加优先级并在evaluatepostfix的switch中添加逻辑;7.支持函数调用需增加函数注册表、修改infixtopostfix识别函数名、并在evaluatepostfix中调用对应函数。

如何用C++实现一个简单的计算器 控制台输入输出和基本运算处理

用C++实现一个简单的计算器,核心在于解析用户输入的字符串,识别数字和运算符,然后按照运算优先级进行计算。 这听起来简单,但细节很多,比如错误处理、不同数据类型的兼容性等等。

如何用C++实现一个简单的计算器 控制台输入输出和基本运算处理

解决方案

如何用C++实现一个简单的计算器 控制台输入输出和基本运算处理

首先,我们需要一个主函数来接收用户的输入,并调用相应的函数进行处理。

立即学习“C++免费学习笔记(深入)”;

#include #include #include #include #include #include #include #include using namespace std;// 定义运算符优先级int precedence(char op) {    if (op == '+' || op == '-')        return 1;    if (op == '*' || op == '/')        return 2;    if (op == '^') // 指数运算        return 3;    return 0;}// 中缀表达式转后缀表达式queue infixToPostfix(const string& expression) {    queue postfixQueue;    stack operatorStack;    stringstream ss(expression);    string token;    while (ss >> token) {        if (isdigit(token[0]) || (token.size() > 1 && isdigit(token[1]) && (token[0] == '-' || token[0] == '+'))) {            // 数字直接入队列 (处理负数)            postfixQueue.push(token);        } else if (token == "(") {            operatorStack.push('(');        } else if (token == ")") {            while (!operatorStack.empty() && operatorStack.top() != '(') {                postfixQueue.push(string(1, operatorStack.top()));                operatorStack.pop();            }            if (!operatorStack.empty() && operatorStack.top() == '(') {                operatorStack.pop(); // 弹出 '('            } else {                throw invalid_argument("Mismatched parentheses"); // 括号不匹配            }        } else {            // 运算符处理            char op = token[0]; // 假设token长度为1            while (!operatorStack.empty() && precedence(op) <= precedence(operatorStack.top())) {                postfixQueue.push(string(1, operatorStack.top()));                operatorStack.pop();            }            operatorStack.push(op);        }    }    // 将剩余运算符弹出    while (!operatorStack.empty()) {        if (operatorStack.top() == '(') {            throw invalid_argument("Mismatched parentheses"); // 括号不匹配        }        postfixQueue.push(string(1, operatorStack.top()));        operatorStack.pop();    }    return postfixQueue;}// 计算后缀表达式double evaluatePostfix(queue postfixQueue) {    stack operandStack;    while (!postfixQueue.empty()) {        string token = postfixQueue.front();        postfixQueue.pop();        if (isdigit(token[0]) || (token.size() > 1 && isdigit(token[1]) && (token[0] == '-' || token[0] == '+'))) {            // 数字入栈            operandStack.push(stod(token));        } else {            // 运算符处理            if (operandStack.size() < 2) {                throw invalid_argument("Invalid expression"); // 缺少操作数            }            double operand2 = operandStack.top();            operandStack.pop();            double operand1 = operandStack.top();            operandStack.pop();            char op = token[0];            switch (op) {                case '+': operandStack.push(operand1 + operand2); break;                case '-': operandStack.push(operand1 - operand2); break;                case '*': operandStack.push(operand1 * operand2); break;                case '/':                    if (operand2 == 0) {                        throw invalid_argument("Division by zero"); // 除数为零                    }                    operandStack.push(operand1 / operand2);                    break;                case '^': operandStack.push(pow(operand1, operand2)); break;                default: throw invalid_argument("Invalid operator"); // 无效运算符            }        }    }    if (operandStack.size() != 1) {        throw invalid_argument("Invalid expression"); // 表达式无效    }    return operandStack.top();}int main() {    string expression;    cout << "请输入算术表达式(用空格分隔数字和运算符,支持+ - * / ^):" << endl;    getline(cin, expression);    try {        queue postfixQueue = infixToPostfix(expression);        double result = evaluatePostfix(postfixQueue);        cout << "结果: " << result << endl;    } catch (const exception& e) {        cerr << "错误: " << e.what() << endl;        return 1;    }    return 0;}

这段代码首先定义了运算符的优先级,然后实现了一个中缀表达式转后缀表达式的函数

infixToPostfix

,最后实现了一个计算后缀表达式的函数

evaluatePostfix

。 主函数负责接收用户输入,调用这两个函数,并输出结果。当然,这段代码还包含了一些错误处理,比如括号不匹配、除数为零等等。

如何用C++实现一个简单的计算器 控制台输入输出和基本运算处理

如何处理用户输入中的空格?

在上面的代码中,我们使用了

stringstream

来处理用户输入。

stringstream

会自动忽略空格,并将字符串分割成一个个的 token。 因此,用户可以在输入表达式时随意添加空格,程序仍然可以正确解析。

如何扩展计算器的功能,比如添加更多运算符?

要添加更多运算符,首先需要在

precedence

函数中定义新运算符的优先级。 然后,在

evaluatePostfix

函数的

switch

语句中添加新运算符的处理逻辑。 例如,要添加求模运算符

%

,可以这样修改代码:

// 在 precedence 函数中添加 % 的优先级int precedence(char op) {    if (op == '+' || op == '-')        return 1;    if (op == '*' || op == '/')        return 2;    if (op == '%') // 求模运算        return 2;    if (op == '^') // 指数运算        return 3;    return 0;}// 在 evaluatePostfix 函数的 switch 语句中添加 % 的处理逻辑switch (op) {    case '+': operandStack.push(operand1 + operand2); break;    case '-': operandStack.push(operand1 - operand2); break;    case '*': operandStack.push(operand1 * operand2); break;    case '/':        if (operand2 == 0) {            throw invalid_argument("Division by zero"); // 除数为零        }        operandStack.push(operand1 / operand2);        break;    case '%':        if (operand2 == 0) {            throw invalid_argument("Division by zero"); // 除数为零        }        operandStack.push(fmod(operand1, operand2)); // 使用 fmod 处理浮点数求模        break;    case '^': operandStack.push(pow(operand1, operand2)); break;    default: throw invalid_argument("Invalid operator"); // 无效运算符}

注意,求模运算需要使用

fmod

函数来处理浮点数。

如何处理更复杂的表达式,比如包含函数调用?

处理包含函数调用的表达式会更复杂。 首先,需要在

infixToPostfix

函数中识别函数名和参数。 然后,在

evaluatePostfix

函数中调用相应的函数,并将结果压入栈中。 这需要一个函数注册表,将函数名和函数指针关联起来。 例如:

#include // 定义函数指针类型typedef double (*FunctionPtr)(double);// 函数注册表map functionTable;// 注册函数void registerFunction(const string& name, FunctionPtr function) {    functionTable[name] = function;}// 实现一个示例函数double sine(double x) {    return sin(x);}int main() {    // 注册 sine 函数    registerFunction("sin", sine);    // ... (修改 infixToPostfix 和 evaluatePostfix 函数)    return 0;}

然后,需要修改

infixToPostfix

函数,识别函数调用,并将函数名和参数转换为后缀表达式。 例如,将

sin(3.14)

转换为

3.14 sin

。 最后,修改

evaluatePostfix

函数,当遇到函数名时,从函数注册表中查找函数指针,并调用该函数。这部分代码比较复杂,需要仔细设计和实现。

以上就是如何用C++实现一个简单的计算器 控制台输入输出和基本运算处理的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1470826.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
C++多线程中怎样避免虚假共享 缓存行填充技术
上一篇 2025年12月18日 18:35:09
范围for循环背后机制 基于迭代器的语法糖实现
下一篇 2025年12月18日 18:35:21

相关推荐

发表回复

登录后才能评论
关注微信