计算器应用的功能实现可以非常复杂,取决于你希望它具备的能力。以下是一个全面的计算器功能实现指南,分为基本功能、扩展功能、优化和用户界面设计等部分。

完整示例代码免费下载链接

1. 基本功能

a. 基本运算

  1. 加法(Addition):计算两个数的和。

    result = num1 + num2;
    
  2. 减法(Subtraction):计算两个数的差。

    result = num1 - num2;
    
  3. 乘法(Multiplication):计算两个数的积。

    result = num1 * num2;
    
  4. 除法(Division):计算两个数的商,注意处理除数为零的情况。

    if (num2 != 0) {
        result = num1 / num2;
    } else {
        std::cout << "错误:除数不能为零。" << std::endl;
    }
    
  5. 取余(Modulus):计算两个整数的余数。

    if (static_cast<int>(num2) != 0) {
        result = static_cast<int>(num1) % static_cast<int>(num2);
    } else {
        std::cout << "错误:除数不能为零。" << std::endl;
    }
    
  6. 幂运算(Exponentiation):计算一个数的幂。

    result = pow(num1, num2);
    

b. 输入处理

  • 获取有效的数字输入

    bool getDoubleInput(double &number) {
        std::cin >> number;
        if (std::cin.fail()) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            return false;
        }
        return true;
    }
    
  • 获取操作符输入

    char getOperatorInput() {
        char op;
        std::cin >> op;
        return op;
    }
    

2. 扩展功能

a. 括号运算和复杂表达式

逆波兰表示法(Postfix Notation):通过转换表达式为后缀形式来处理运算符优先级和括号。

示例解析器(递归下降解析):

#include <iostream>
#include <string>
#include <cctype>
#include <cmath>
#include <stdexcept>

class Calculator {
public:
    explicit Calculator(const std::string& expression) : expr(expression), pos(0) {}

    double evaluate() {
        return parseExpression();
    }

private:
    std::string expr;
    size_t pos;

    double parseExpression() {
        double result = parseTerm();
        while (pos < expr.size()) {
            char op = expr[pos];
            if (op == '+' || op == '-') {
                pos++;
                double term = parseTerm();
                if (op == '+') result += term;
                else result -= term;
            } else {
                break;
            }
        }
        return result;
    }

    double parseTerm() {
        double result = parseFactor();
        while (pos < expr.size()) {
            char op = expr[pos];
            if (op == '*' || op == '/') {
                pos++;
                double factor = parseFactor();
                if (op == '*') result *= factor;
                else result /= factor;
            } else {
                break;
            }
        }
        return result;
    }

    double parseFactor() {
        double result;
        if (expr[pos] == '(') {
            pos++;
            result = parseExpression();
            if (expr[pos] == ')') pos++;
        } else if (isdigit(expr[pos]) || expr[pos] == '.') {
            size_t end;
            result = std::stod(expr.substr(pos), &end);
            pos += end;
        } else if (expr[pos] == '-') {
            pos++;
            result = -parseFactor();
        } else {
            throw std::runtime_error("Unexpected character");
        }
        return result;
    }
};

b. 三角函数和对数函数

三角函数(例如 sin, cos, tan):

#include <cmath>
#include <iostream>

void calculateTrigonometricFunctions(double angle) {
    std::cout << "sin(" << angle << ") = " << sin(angle) << std::endl;
    std::cout << "cos(" << angle << ") = " << cos(angle) << std::endl;
    std::cout << "tan(" << angle << ") = " << tan(angle) << std::endl;
}

对数函数(例如 loglog10):

#include <cmath>
#include <iostream>

void calculateLogarithms(double value) {
    if (value > 0) {
        std::cout << "log(" << value << ") = " << log(value) << std::endl;
        std::cout << "log10(" << value << ") = " << log10(value) << std::endl;
    } else {
        std::cout << "错误:对数的底数必须大于零。" << std::endl;
    }
}

c. 复数运算

复数的基本运算

#include <iostream>
#include <complex>

void performComplexOperations() {
    std::complex<double> a(1.0, 2.0);
    std::complex<double> b(3.0, 4.0);

    std::cout << "a = " << a << std::endl;
    std::cout << "b = " << b << std::endl;
    std::cout << "a + b = " << (a + b) << std::endl;
    std::cout << "a - b = " << (a - b) << std::endl;
    std::cout << "a * b = " << (a * b) << std::endl;
    std::cout << "a / b = " << (a / b) << std::endl;
}

3. 优化建议

a. 历史记录功能

保存和加载历史记录

#include <vector>
#include <fstream>
#include <string>

void saveHistory(const std::vector<std::string>& history) {
    std::ofstream outFile("history.txt");
    for (const auto& entry : history) {
        outFile << entry << std::endl;
    }
}

void loadHistory(std::vector<std::string>& history) {
    std::ifstream inFile("history.txt");
    std::string line;
    while (std::getline(inFile, line)) {
        history.push_back(line);
    }
}

b. 改进用户界面

图形用户界面(GUI):可以使用 Qt 或 wxWidgets。以下是一个简单的 Qt 示例:

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QMessageBox>

class Calculator : public QWidget {
    Q_OBJECT

public:
    Calculator() {
        QVBoxLayout *layout = new QVBoxLayout(this);

        input = new QLineEdit(this);
        layout->addWidget(input);

        QPushButton *calculateButton = new QPushButton("Calculate", this);
        layout->addWidget(calculateButton);

        connect(calculateButton, &QPushButton::clicked, this, &Calculator::calculate);

        setLayout(layout);
    }

private slots:
    void calculate() {
        QString text = input->text();
        // 这里需要添加计算逻辑
        QMessageBox::information(this, "Result", "Result of: " + text);
    }

private:
    QLineEdit *input;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    Calculator calc;
    calc.show();
    return app.exec();
}

c. 单元测试

使用 Google Test 进行单元测试

#include <gtest/gtest.h>
#include <cmath>

TEST(MathFunctionsTest, SinFunction) {
    EXPECT_NEAR(sin(0), 0, 1e-9);
    EXPECT_NEAR(sin(M_PI / 2), 1, 1e-9);
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

d. 输入验证

改进输入验证

bool getDoubleInput(double &number) {
    std::string input;
    std::cin >> input;
    try {
        number = std::stod(input);
        return true;
    } catch (const std::invalid_argument&) {
        std::cout << "无效的输入,请输入有效的数字。" << std::endl;
        return false;
    }
}

总结

通过这些功能的实现,你可以创建一个功能强大且用户友好的计算器应用。可以根据需要进一步扩展功能,例如支持更多数学函数、增加对复数的支持、优化性能等。同时,优化用户界面和确保代码质量也是提升用户体验的重要方面。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐