C语言实现简易计算器:算术表达式计算及合法性校验
这是一个简易的计算器程序,使用 C 语言实现,可以进行算术表达式的计算。程序运行后会显示一个封面,上面列出了可选择的操作。用户可以输入序号选择进行的操作,包括算术表达式计算和退出程序。
-
算术表达式计算: a. 输入 1 选择进行算术表达式计算操作; b. 程序会要求用户输入要计算的表达式; c. 用户输入表达式后,程序会判断表达式是否合法:
- 表达式中只能包含数字、运算符和括号;
- 连续的乘号或除号是不合法的;
- 连续的加号或减号是不合法的; d. 如果表达式合法,程序会计算表达式的结果并输出; e. 如果表达式不合法,程序会提示用户输入正确的表达式; f. 用户可以反复进行表达式计算,直到选择退出程序。
-
退出程序: a. 输入 0 选择退出程序; b. 程序会清屏并结束运行。
#include <stdio.h>
#include <stdlib.h>
#define max 100
void Name() //封面
{
printf('---------------------------------
');
printf(' 这是一个简易的计算器
');
printf(' 请输入序号选择你要进行的操作:
');
printf(' 算术表达计算
');
printf('0.退出程序
');
printf('---------------------------------
');
}
typedef struct {
int data[max];
int top;
} SqStack;
SqStack* InitStack() //初始化栈
{
SqStack *s = (SqStack*)malloc(sizeof(SqStack));
s->top = -1; //初始化栈顶指针
return s;
}
int StackEmpty(SqStack s) //判断栈是否为空
{
if (s.top == -1) return 1; //为空
else return 0; //不为空
}
int PushStack(SqStack *s, int x) //压栈操作
{
if (s->top == max - 1) return 0;
s->top++;
s->data[s->top] = x;
return 1;
}
int PopStack(SqStack *s) //出栈操作
{
if (s->top == -1) return 0;
return s->data[s->top--];
}
int Priority(char u) //判断运算符的优先级
{
switch (u) {
case '+':
case '-': return 1;
case '*':
case '/': return 2;
default: return -1;
}
}
void PopPush(SqStack *OPTR, SqStack *OPND)
{
//两操作数、操作符出栈,计算结果,结果入栈
char u;
int x1, x2, sum;
u = PopStack(OPTR); //将操作符出栈
x1 = PopStack(OPND); //将两个操作数出栈
x2 = PopStack(OPND);
switch (u) { //根据出栈操作符选择计算方式
case '+': sum = x2 + x1; break;
case '-': sum = x2 - x1; break;
case '*': sum = x2 * x1; break;
case '/': sum = x2 / x1; break;
}
PushStack(OPND, sum); //将计算得到的数 重新入操作数栈
}
int Count(char *s) //扫描表达式并计算
{
SqStack *OPTR, *OPND; //建立两个栈
OPTR = InitStack(); //分别初始化
OPND = InitStack();
while (*s != '�') { //扫描表达式直到扫描结束为止
if (*s >= '0' && *s <= '9') { //扫描到数字
int y = *s - '0'; //将字符转为数字
s++; //扫描的指针往下移
while (*s >= '0' && *s <= '9') { //处理多位数
y = y * 10 + *s - '0'; //最开始得到的元素往前移
s++; //扫描指针往后移
}
PushStack(OPND, y); //入操作数栈
}
else if (OPTR->top == -1 || *s == '(' || Priority(*s) > Priority(OPTR->data[OPTR->top])) { //扫描到运算符
//如果扫描的栈为空、左括号、运算符优先级>运算符栈顶优先级
PushStack(OPTR, *s); //则运算符压入运算符栈
s++; //扫描的指针继续往下移
if (*s == '-') { //添加负号的情况
PushStack(OPND, 0); //将 0 入操作数栈
}
}
else if (*s == ')' && OPTR->data[OPTR->top] == '(') {
//如果扫描到右括号且栈顶为左括号
PopStack(OPTR); //将左括号出栈
s++; //扫描的指针继续往下移
}
else //扫描到的运算符优先级<=运算符栈顶优先级
PopPush(OPTR, OPND); //将进行计算操作
}
while (OPTR->top >= 0) //表达式扫描完成,将所有运算符出栈
PopPush(OPTR, OPND); //并计算放入操作数栈
int n = OPND->data[OPND->top]; //将最后操作数进行出栈
free(OPTR); //释放两栈
free(OPND);
return n; //返回结果
}
int test(char *s) //判断输入表达式是否合法
{
while (*s != '�') {
if (*s >= '0' && *s <= '9' || *s == '(' || *s == ')') {
s++;
}
else if (*s == '*' || *s == '/') { //当连续*/时
s++;
if (*s == '*' || *s == '/')
return 0;
}
else if (*s == '-' || *s == '+') { //当连续+-时
s++;
if (*s == '-' || *s == '+')
return 0;
}
else //当非数字、运算符等
return 0;
}
return 1;
}
int main()
{
Name(); //引用封面函数
char c[50];
int x, flgh = 1;
while (flgh) {
printf("请输入你的选择 :
");
scanf("%d", &x);
switch (x) {
case 0: flgh = 0; system("cls"); break;
case 1: printf("请输入你要计算的表达式:(如果是负数请加括号)
");
getchar(); //便于接下来表达式的输出
gets(c); //输入计算表达值
if (test(c) == 0) { //判断表达式是否合法
printf("请输入正确的表达式!
");
}
else
printf("计算都得到的:%s=%d
", c, Count(c));
break;
default: printf("请输入正确的序号!
"); break;
}
}
system("pause");
return 0;
}
原文地址: https://www.cveoy.top/t/topic/pdgb 著作权归作者所有。请勿转载和采集!