要用C语言编写一个栈计算器,可以按照以下步骤进行:
// 定义栈结构
typedef struct {
int top;
double stack[MAX_SIZE];
} Stack;
// 初始化栈
void init(Stack* stack) {
stack->top = -1;
}
// 判断栈是否为空
int isEmpty(Stack* stack) {
return stack->top == -1;
}
// 判断栈是否已满
int isFull(Stack* stack) {
return stack->top == MAX_SIZE - 1;
}
// 入栈
void push(Stack* stack, double value) {
if (isFull(stack)) {
printf("Stack is full\n");
exit(1);
}
stack->stack[++stack->top] = value;
}
// 出栈
double pop(Stack* stack) {
if (isEmpty(stack)) {
printf("Stack is empty\n");
exit(1);
}
return stack->stack[stack->top--];
}
// 查看栈顶元素
double peek(Stack* stack) {
if (isEmpty(stack)) {
printf("Stack is empty\n");
exit(1);
}
return stack->stack[stack->top];
}
```c
// 判断运算符的优先级
int getPriority(char c) {
if (c == '^') {
return 3; // 指数运算符(幂)
} else if (c == '*' || c == '/') {
return 2; // 乘法和除法运算符
} else if (c == '+' || c == '-') {
return 1; // 加法和减法运算符
} else {
return 0; // 数字或其他非运算符
}
}
// 将中缀表达式转换为逆波兰表达式
void infixToPostfix(char infix, char postfix) {
Stack stack;
init(&stack);
int i = 0; // 中缀表达式索引
int j = 0; // 逆波兰表达式索引
while (infix[i] != '\0') {
char ch = infix[i];
// 如果是数字,直接添加到逆波兰表达式
if (isdigit(ch) || ch == '.') {
postfix[j++] = ch;
}
// 如果是运算符
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == '(' || ch == ')') {
// 如果是左括号,直接入栈
if (ch == '(') {
push(&stack, ch);
}
// 如果是右括号,将栈中的运算符弹出直到遇到左括号
else if (ch == ')') {
while (!isEmpty(&stack) && peek(&stack) != '(') {
postfix[j++] = pop(&stack);
}
if (!isEmpty(&stack) && peek(&stack) == '(') {
pop(&stack); // 弹出左括号
} else {
printf("Invalid expression\n");
exit(1);
}
}
// 如果是其他运算符,比较优先级后处理
else {
while (!isEmpty(&stack) && getPriority(ch) <= getPriority(peek(&stack))) {
postfix[j++] = pop(&stack);
}
push(&stack, ch);
}
}
i++;
}
// 将栈中剩余的运算符弹出
while (!isEmpty(&stack)) {
if (peek(&stack) == '(') {
printf("Invalid expression\n");
exit(1);
}
postfix[j++] = pop
使用C语言实现栈计算器的示例代码。该代码支持带小数、带括号的四则运算和幂运算。该代码使用栈数据结构来实现计算器功能。
c
Copy
/ 定义栈结构体 /
typedef struct {
double items[MAX_STACK_SIZE];
int top;
} Stack;
/ 初始化栈 /
void init_stack(Stack *s) {
s->top = -1;
}
/ 判断栈是否为空 /
int is_empty(Stack *s) {
return s->top == -1;
}
/ 判断栈是否已满 /
int is_full(Stack *s) {
return s->top == MAX_STACK_SIZE - 1;
}
/ 将元素压入栈 /
void push(Stack *s, double value) {
if (is_full(s)) {
printf("Stack Overflow\n");
exit(1);
}
s->top++;
s->items[s->top] = value;
}
/ 从栈中弹出元素 /
double pop(Stack *s) {
if (is_empty(s)) {
printf("Stack Underflow\n");
exit(1);
}
double value = s->items[s->top];
s->top--;
return value;
}
/ 获取栈顶元素 /
double peek(Stack *s) {
if (is_empty(s)) {
printf("Stack Underflow\n");
exit(1);
}
return s->items[s->top];
}
/ 判断字符是否为运算符 /
int is_operator(char ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^';
}
/ 获取运算符的优先级 /
int get_precedence(char ch) {
switch (ch) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
default:
return 0;
}
}
/ 执行二元运算 /
double perform_operation(double num1, double num2, char operator) {
switch (operator) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '':
return num1 num2;
case '/':
return num1 / num2;
case '^':
return pow(num1, num2);
default:
return 0.0;
}
}
/ 计算表达式 /
double evaluate_expression(const char expr) {
Stack operand_stack; / 操作数栈 /
Stack operator_stack; / 运算符栈 */
init_stack(&operand_stack);
init_stack(&operator_stack);
int i = 0;
while (expr[i] != '\0') {
/* 如果当前字符是空格,忽略它 */
if (expr[i] == ' ') {
i++;
continue;
}
/* 如果当前字符是数字或小数点,获取完整的数值并将其推入操作数栈 */
if (isdigit(expr[i]) || expr[i] == '.') {
double value = 0.0;
int decimal_places = 0;
while (isdigit(expr[i]) || expr[i] == '.') {
if (expr[i] == '.') {
decimal_places = 1;
} else {
value = value * 10 + (expr[i] - '0');
if (decimal_places > 0) {
decimal_places++;
}
}
i++;
}
if (decimal_places > 0) {
value = value / pow(10, decimal_places - 1);
}
push(&operand_stack, value);
continue;
}
/* 如果当前字符是左括号,将其推入运算符栈 */
if (expr[i] == '(') {
push(&operator_stack, expr[i]);
i++;
continue;
}
/* 如果当前字符是右括号,从运算符栈中弹出运算符和操作数,执行相应的操作直到遇到左括号 */
if (expr[i] == ')') {
while (peek(&operator_stack) != '(') {
char operator = (char)pop(&operator_stack);
double num2 = pop(&operand_stack);
double num1 = pop(&operand_stack);
double result = perform_operation(double)num1, (double)num2, operator);
push(&operand_stack, result);
}
pop(&operator_stack);
i++;
continue;
}
/* 如果当前字符是运算符,将其推入运算符栈。如果当前运算符的优先级低于或等于栈顶运算符的优先级,则从运算符栈中弹出运算符和操作数,执行相应的操作 */
if (is_operator(expr[i])) {
while (!is_empty(&operator_stack) && get_precedence(expr[i]) <= get_precedence(peek(&operator_stack))) {
char operator = (char)pop(&operator_stack);
double num2 = pop(&operand_stack);
double num1 = pop(&operand_stack);
double result = perform_operation((double)num1, (double)num2, operator);
push(&operand_stack, result);
}
push(&operator_stack, expr[i]);
i++;
continue;
}
/* 如果表达式中存在未知字符,则无法计算 */
printf("Invalid Character Found: %c\n", expr[i]);
exit(1);
}
/* 如果表达式已经扫描完但是运算符栈不为空,则从运算符栈中弹出运算符和操作数,执行相应的操作 */
while (!is_empty(&operator_stack)) {
char operator = (char)pop(&operator_stack);
double num2 = pop(&operand_stack);
double num1 = pop(&operand_stack);
double result = perform_operation((double)num1, (double)num2, operator);
push(&operand_stack, result);
}
/* 最后,操作数栈中的唯一元素即为结果 */
return pop(&operand_stack);
}
int main() {
char expr[MAX_STACK_SIZE];
printf("Enter an expression: ");
fgets(expr, MAX_STACK_SIZE, stdin);
double result = evaluate_expression(expr);
printf("Result: %.2lf\n", result);
return 0;
}
代码中的主要思路是将表达式中的数字和运算符分别推入操作数栈和运算符栈,并在需要时从栈中弹出元素进行计算。该代码可以读入带括号、带小数的四则运算表达式,支持幂运算,能输出结果精确到小数点后两位。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。