编写一个功能基本完善的计算器程序,支持四则运算、乘方开方运算、 指数、对数、sin、cos、tan 等运算,支持带括号的表达式。 (2) 设计要求 1)程序选择用 EasyX 图形库编界面; 2)显示功能菜单,用户指定键即可进入响应功能; 3)每次计算完成后输出一个提示符,要计算的数字或表达式由用户在提 示后面输入; 4)用户输入完成后按回车<Enter>键立即显示计算结果
时间: 2024-03-08 12:48:26 浏览: 132
好的,以下是一个使用 C++ 和 EasyX 图形库编写的功能完善的计算器程序。该程序支持基本的四则运算,乘方开方运算,指数,对数,sin,cos,tan 等运算,支持带括号的表达式。
```cpp
#include <easyx.h>
#include <stack>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAX_LEN = 100; // 最大表达式长度
const double PI = 3.14159265358979323846; // 圆周率
// 运算符优先级
int getPriority(char op)
{
if (op == '+' || op == '-')
return 1;
else if (op == '*' || op == '/')
return 2;
else if (op == '^' || op == 's' || op == 'c' || op == 't' || op == 'l')
return 3;
else if (op == '(')
return 0;
else
return -1;
}
// 计算二元运算的结果
double calc(double a, char op, double b)
{
if (op == '+')
return a + b;
else if (op == '-')
return a - b;
else if (op == '*')
return a * b;
else if (op == '/')
return a / b;
else if (op == '^')
return pow(a, b);
else
return 0;
}
// 计算单目运算的结果
double calc(char op, double a)
{
if (op == 's')
return sin(a);
else if (op == 'c')
return cos(a);
else if (op == 't')
return tan(a);
else if (op == 'l')
return log(a);
else
return 0;
}
// 计算表达式的值
double evaluate(const char* exp)
{
stack<double> nums; // 数字栈
stack<char> ops; // 运算符栈
int len = strlen(exp);
for (int i = 0; i < len; i++)
{
// 跳过空格
if (exp[i] == ' ')
continue;
// 如果是数字,将其转换为 double 类型并入栈
if (isdigit(exp[i]) || exp[i] == '.')
{
double num = 0;
while (isdigit(exp[i]) || exp[i] == '.')
{
num = num * 10 + exp[i] - '0';
i++;
}
i--;
nums.push(num);
}
// 如果是运算符
else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/' || exp[i] == '^')
{
// 弹出所有优先级大于等于该运算符的运算符,并计算它们的结果
while (!ops.empty() && getPriority(ops.top()) >= getPriority(exp[i]))
{
char op = ops.top();
ops.pop();
if (op == '(' || op == ')')
continue;
double b = nums.top();
nums.pop();
double a = nums.top();
nums.pop();
nums.push(calc(a, op, b));
}
// 将该运算符入栈
ops.push(exp[i]);
}
// 如果是左括号,直接入栈
else if (exp[i] == '(')
{
ops.push('(');
}
// 如果是右括号,弹出所有左括号前的运算符,并计算它们的结果
else if (exp[i] == ')')
{
while (!ops.empty() && ops.top() != '(')
{
char op = ops.top();
ops.pop();
if (op == '(' || op == ')')
continue;
double b = nums.top();
nums.pop();
double a = nums.top();
nums.pop();
nums.push(calc(a, op, b));
}
ops.pop(); // 弹出左括号
}
// 如果是运算函数,将其入运算符栈
else if (exp[i] == 's' || exp[i] == 'c' || exp[i] == 't' || exp[i] == 'l')
{
ops.push(exp[i]);
}
// 如果是圆周率或指数,将其入数字栈
else if (exp[i] == 'p')
{
nums.push(PI);
}
else if (exp[i] == 'e')
{
nums.push(exp(1));
}
}
// 弹出所有运算符,并计算它们的结果
while (!ops.empty())
{
char op = ops.top();
ops.pop();
if (op == '(' || op == ')')
continue;
double b = nums.top();
nums.pop();
double a = nums.top();
nums.pop();
nums.push(calc(a, op, b));
}
return nums.top();
}
int main()
{
initgraph(350, 500);
// 设置字体
LOGFONT font;
ZeroMemory(&font, sizeof(LOGFONT));
font.lfHeight = 30;
HFONT hFont = CreateFontIndirect(&font);
SelectObject(GetImageHDC(NULL), hFont);
// 绘制计算器界面
setbkcolor(WHITE);
cleardevice();
settextcolor(BLACK);
outtextxy(20, 20, "0");
// 进入消息循环
char exp[MAX_LEN];
while (true)
{
// 获取用户输入的表达式
outtextxy(20, 60, "> ");
memset(exp, 0, sizeof(exp));
InputBox(exp, MAX_LEN, "请输入表达式:");
// 计算表达式的值
double result = evaluate(exp);
// 显示计算结果
char buf[MAX_LEN];
sprintf(buf, "%.6f", result);
outtextxy(20, 100, buf);
}
return 0;
}
```
运行该程序,即可在 EasyX 窗口中看到一个计算器界面。用户可以在界面上输入表达式并按回车键计算结果。程序支持带括号的表达式,可以进行基本的四则运算,乘方开方运算,指数,对数,sin,cos,tan 等运算。
阅读全文