用栈运用void initstack():初始化栈、int Make_str():语法检查并计算、int push_operator(int operator):将运算符压入栈、int push_num(double num):将运算数压入栈、int procede(int operator):处理运算符、int change_opnd(int operator):将字符型运算符转换成优先级、int push_opnd(int operator):将运算符压入栈、int pop_opnd():将运算符弹出栈、int caculate(int cur_opnd):简单计算+,-,*、double pop_num():弹出运算数编译计算器
时间: 2023-12-10 10:04:11 浏览: 52
好的,我会尽力回答你的问题,关于编译计算器的问题,我可以给你一些思路:
1. 首先需要定义一个栈结构,用于存储运算符和运算数。栈中的元素可以是运算符或运算数,我们可以使用一个结构体来表示这些元素,例如:
```
typedef struct {
int type; // 元素类型,0表示运算符,1表示运算数
union {
double num; // 运算数值
int op; // 运算符,用整数表示
} content;
} Element;
```
2. 接下来需要实现一些栈操作函数,例如初始化栈、压栈、弹栈等。这些函数可以使用指针来实现栈的操作,例如:
```
void initstack(Element *stack, int *top) {
*top = -1; // 初始化栈顶指针
}
void push(Element *stack, int *top, Element e) {
(*top)++; // 栈顶指针加1
stack[*top] = e; // 将元素压入栈中
}
Element pop(Element *stack, int *top) {
Element e = stack[*top]; // 获取栈顶元素
(*top)--; // 栈顶指针减1
return e; // 返回弹出的元素
}
```
3. 接着需要实现一个字符串解析函数,用于将算术表达式转换成元素序列。这个函数可以使用一个指针来遍历字符串,根据不同的字符类型来生成不同的元素。例如:
```
int Make_str(char *str, Element *elems, int *n) {
int len = strlen(str);
int i = 0;
while (i < len) {
char c = str[i];
if (isdigit(c) || c == '.') { // 数字
double num = 0;
int k = 0;
while (isdigit(str[i]) || str[i] == '.') {
if (str[i] == '.') {
k = 1;
} else {
if (k == 0) {
num = num * 10 + (str[i] - '0');
} else {
num = num + (str[i] - '0') * pow(0.1, k);
k++;
}
}
i++;
}
Element e;
e.type = 1;
e.content.num = num;
elems[*n] = e;
(*n)++;
} else if (c == '+' || c == '-' || c == '*' || c == '/') { // 运算符
int op;
if (c == '+') {
op = 1;
} else if (c == '-') {
op = 2;
} else if (c == '*') {
op = 3;
} else {
op = 4;
}
Element e;
e.type = 0;
e.content.op = op;
elems[*n] = e;
(*n)++;
i++;
} else { // 忽略其他字符
i++;
}
}
return 1;
}
```
4. 在解析完元素序列之后,就可以开始计算表达式了。我们可以使用两个栈来实现计算过程,一个存储运算符,另一个存储运算数。具体的计算过程可以参考下面的代码:
```
double calculate(char *str) {
Element elems[MAX_SIZE];
int n = 0;
Make_str(str, elems, &n); // 解析表达式,生成元素序列
Element opnd[MAX_SIZE]; // 运算数栈
Element optr[MAX_SIZE]; // 运算符栈
int top1, top2;
initstack(opnd, &top1); // 初始化运算数栈
initstack(optr, &top2); // 初始化运算符栈
push(optr, &top2, elems[0]); // 将第一个元素压入运算符栈
int i = 1;
while (i < n) {
Element e = elems[i];
if (e.type == 1) { // 如果是运算数,直接压入运算数栈
push(opnd, &top1, e);
i++;
} else { // 如果是运算符
Element top = optr[top2]; // 获取运算符栈顶元素
int p = change_opnd(top.content.op); // 将字符型运算符转换成优先级
int q = change_opnd(e.content.op);
if (p < q) { // 如果优先级比栈顶元素高,直接压入运算符栈
push(optr, &top2, e);
i++;
} else if (p > q) { // 如果优先级比栈顶元素低,弹出运算符和运算数进行计算
Element op = pop(optr, &top2);
double b = pop_num(&opnd, &top1);
double a = pop_num(&opnd, &top1);
double res = caculate(a, b, op.content.op); // 简单计算
Element tmp;
tmp.type = 1;
tmp.content.num = res;
push(opnd, &top1, tmp); // 将计算结果压入运算数栈
} else { // 如果优先级相同,弹出栈顶运算符进行计算
pop(optr, &top2);
double b = pop_num(&opnd, &top1);
double a = pop_num(&opnd, &top1);
double res = caculate(a, b, top.content.op); // 简单计算
Element tmp;
tmp.type = 1;
tmp.content.num = res;
push(opnd, &top1, tmp); // 将计算结果压入运算数栈
}
}
}
while (top2 >= 0) { // 处理剩余的运算符
Element op = pop(optr, &top2);
double b = pop_num(&opnd, &top1);
double a = pop_num(&opnd, &top1);
double res = caculate(a, b, op.content.op); // 简单计算
Element tmp;
tmp.type = 1;
tmp.content.num = res;
push(opnd, &top1, tmp); // 将计算结果压入运算数栈
}
return pop_num(&opnd, &top1); // 返回最终的计算结果
}
```
以上就是一个简单的编译计算器的实现思路,具体的实现细节还需要根据实际情况进行调整。