C++实现无函数/数组的简单四则运算计算器

温以宁
温以宁
发布时间:2026-10-16 | 5人浏览过
原创

本文介绍了如何在不使用数组和自定义函数的限制下,利用C++的分支与循环结构实现一个支持四则运算且遵循“先乘除后加减”优先级的简易计算器,包含源码解析与运行效果展示。

设计背景与需求

本项目的核心目标是在严格的编程限制下进行算法练习。为了模拟只学习了基础控制流语句的初学者思维,代码需满足以下约束条件:

  1. 语法限制:仅允许使用 if、switch 分支语句和 while 循环语句;严禁使用数组存储数据,严禁定义或调用任何自定义函数。
  2. 功能要求:支持加、减、乘、除四则运算。当输入序列中包含多个运算符时,程序必须严格遵循数学运算优先级,即先处理乘法与除法,再处理加法与减法。
  3. 排除项:不支持括号运算。

尽管这是一个基础的计算器原型,但在上述严苛的限制下,需要精巧地通过变量状态流转和嵌套循环来实现运算逻辑。

核心逻辑解析

第1步:变量声明与初始化

由于不能使用数组来暂存操作数序列,程序采用逐个读取的方式处理输入流。声明必要的浮点型变量用于存储数值,字符型变量用于缓存运算符:

  • double a0, a1, a2:a0 用于累计最终的加减结果,a1 用于暂存连乘或连除中间结果,a2 用于读取后续的乘除操作数。
  • char ca1, ca2:ca1 记录当前参与计算的主要运算符,ca2 记录新读取到的下一个运算符。

第2步:初始输入与边界判断

程序首先尝试读取第一个数字和第一个符号:cin >> a0 >> ca1;。 此时进入一个简单的判定分支:如果第一个符号直接就是等号(=),说明用户只输入了一个数,程序直接输出 a0 并结束。若否则进入主计算流程。

第3步:构建主循环处理加减法

在进入第二个数值的读取后,程序进入一个无限循环 while(1),该循环主要负责任务调度,根据读取到的新运算符类型决定后续动作:

  • 遇到等号(=):表明输入结束。根据前一个运算符 ca1 的类型,将累加值 a0 与暂存值 a1 进行最终的加减乘除运算,随后跳出循环输出结果。
  • 遇到加减号(+/-):同样触发当前的运算结算(根据 ca1 执行操作)。结算完成后,需要将新的运算符赋值给 ca1,并继续循环以读取下一组数对(a1 和 ca2)。
  • 遇到乘除号(*//):这是最复杂的部分。由于优先级高,不能立即将其与 a0 混合计算,而是需要进入内部子循环专门处理一连串的乘除运算。

第4步:子循环处理连乘连除

当检测到 ca2 为 * 或 / 时,程序陷入第二层 while(1) 循环。此阶段的目的是连续消费掉后面所有的同级运算:

  1. 读取下一个数值存入 a2,并将 a1 与 a2 进行乘除运算,更新 a1。
  2. 读取下一个运算符到 ca2。
  3. 检查 ca2:
    • 若是 * /:回到步骤1继续计算。
    • 若是 + - 或 =:说明同级连乘/连除结束。此时先将累积的 a1 结果合并回 a0(作为加减运算处理)。如果是 = 则结束程序,否则将 ca2 赋给 ca1 跳出子循环,回到主循环继续处理剩余部分。

完整代码实现

#include<iostream>
using namespace std;

int main()
{
    // 变量声明:a0负责总体加减结果,a1负责当前连乘/除结果,a2暂存新操作数
    double a0, a1, a2;
    char ca1, ca2;
    
    // 输入第一个数和第一个运算符
    cin >> a0 >> ca1;
    
    if(ca1 == '=') {
        cout << a0 << endl;
    }
    else
    {
        // 输入第二个数 (a1) 和对应的运算符 (ca2)
        cin >> a1 >> ca2;
        
        while(1) // 主循环:处理整体流程,包含加减法逻辑
        {            
            if(ca1 == '=') {
                cout << a0 << endl;
                break;
            } 
            
            switch(ca2) {
                case '=':
                    // 结束符:根据前序运算符完成最后一次运算
                    switch(ca1) {
                        case '+': a0 = a0 + a1; break;
                        case '-': a0 = a0 - a1; break;
                        case '*': a0 = a0 * a1; break;
                        case '/': a0 = a0 / a1;
                    }
                    ca1 = ca2;
                    break;
                    
                case '+':
                case '-':
                    // 发现加减号:先结算之前的运算,准备下一轮
                    switch(ca1) {
                        case '+': a0 = a0 + a1; break;
                        case '-': a0 = a0 - a1; break;
                        case '*': a0 = a0 * a1; break;
                        case '/': a0 = a0 / a1;
                    }
                    ca1 = ca2;
                    cin >> a1 >> ca2;
                    break;
                    
                case '*':
                case '/':
                    // 发现乘除号:进入次级循环处理连续乘除
                    while(1) {
                        switch(ca2) {
                            case '*': 
                                cin >> a2;
                                a1 = a1 * a2;
                                cin >> ca2;
                                break;
                            case '/': 
                                cin >> a2;
                                a1 = a1 / a2;
                                cin >> ca2;
                            // 注意:此处原代码case '/'后缺失break导致fall-through,
                            // 但结合语境通常期望各自独立逻辑,修正如下确保逻辑严谨性:
                            // 若保持原代码意图可能是笔误,此处按标准逻辑补充break以确保正确
                             break; // 补充break防止穿透
                        }
                        
                        if(ca2 == '=') {
                            switch(ca1) {
                                case '+': a0 = a0 + a1; break;
                                case '-': a0 = a0 - a1; break;
                            }
                            ca1 = ca2;
                            break;
                        }
                        
                        if(ca2 == '+' || ca2 == '-') {
                            switch(ca1) {
                                case '+': a0 = a0 + a1; break;
                                case '-': a0 = a0 - a1; break;
                            }
                            ca1 = ca2;
                            cin >> a1 >> ca2;
                            break;
                        }
                    }
            }
        }
    }
    return 0;
}

运行验证

为了验证程序的准确性,我们在控制台输入了包含混合运算符的测试用例。程序能够正确识别并处理运算优先级。

对比系统自带的计算器得出的结果,可以看到两者完全一致,证明逻辑推导是正确的。

注意事项

  • 状态同步:代码中 ca2 对新读入的运算符的处理至关重要。只有当 ca2 更新后,程序才能正确判断是继续累加还是结算当前优先级较高的运算。
  • 变量分工:a0 充当总账,最终输出必须是它。而 a1 仅作为乘法/除法期间的缓冲区,这保证了加减法能等待乘除法结束后再进行合并。

总结

这个案例展示了如何在缺乏高级数据结构辅助的情况下,通过纯粹的控制流指令解决具有优先级的表达式求值问题。理解其中循环嵌套的状态流转机制,对于深入掌握 C++ 基础语法非常有帮助。以上就是C++实现简单的计算器功能的详细内容,更多关于C++基础算法设计的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表