在学习数据结构的过程中,C语言栈式计算器是一个非常经典且实用的项目。它不仅能帮助你深入理解“栈”这种数据结构,还能掌握如何将中缀表达式转换为后缀表达式并进行求值。本教程将手把手带你用C语言实现一个支持加减乘除和括号的简易计算器,即使你是编程小白,也能轻松跟上!

栈(Stack)是一种“后进先出”(LIFO, Last In First Out)的数据结构。你可以把它想象成一摞盘子:你只能从最上面拿盘子,也只能把新盘子放在最上面。
在表达式求值中,栈能高效地处理运算符优先级和括号嵌套问题。例如,当我们遇到 (3 + 5) * 2 时,必须先算括号内的内容。使用两个栈(一个存数字,一个存运算符),我们可以轻松实现这一逻辑。
我们日常写的表达式如 3 + 5 * 2 是中缀表达式(运算符在中间)。但计算机更喜欢后缀表达式(也叫逆波兰表达式),比如 3 5 2 * +。
因此,我们的计算器分为两步:
下面是一个完整的 C 语言栈式计算器代码,支持整数、四则运算和括号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define MAX 100// 数字栈typedef struct { int data[MAX]; int top;} NumStack;// 运算符栈typedef struct { char data[MAX]; int top;} OpStack;// 初始化栈void initNumStack(NumStack *s) { s->top = -1; }void initOpStack(OpStack *s) { s->top = -1; }// 入栈、出栈(数字)void pushNum(NumStack *s, int val) { s->data[++s->top] = val; }int popNum(NumStack *s) { return s->data[s->top--]; }// 入栈、出栈(运算符)void pushOp(OpStack *s, char op) { s->data[++s->top] = op; }char popOp(OpStack *s) { return s->data[s->top--]; }// 判断是否为空int isEmptyNum(NumStack *s) { return s->top == -1; }int isEmptyOp(OpStack *s) { return s->top == -1; }// 获取栈顶char peekOp(OpStack *s) { return s->data[s->top]; }// 判断运算符优先级int precedence(char op) { switch(op) { case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; }}// 中缀转后缀并求值int evaluate(char expr[]) { NumStack nums; OpStack ops; initNumStack(&nums); initOpStack(&ops); for (int i = 0; expr[i] != '\0'; i++) { if (isspace(expr[i])) continue; // 如果是数字 if (isdigit(expr[i])) { int num = 0; while (isdigit(expr[i])) { num = num * 10 + (expr[i] - '0'); i++; } i--; // 回退一位 pushNum(&nums, num); } // 如果是左括号 else if (expr[i] == '(') { pushOp(&ops, expr[i]); } // 如果是右括号 else if (expr[i] == ')') { while (!isEmptyOp(&ops) && peekOp(&ops) != '(') { char op = popOp(&ops); int b = popNum(&nums); int a = popNum(&nums); switch(op) { case '+': pushNum(&nums, a + b); break; case '-': pushNum(&nums, a - b); break; case '*': pushNum(&nums, a * b); break; case '/': pushNum(&nums, a / b); break; } } popOp(&ops); // 弹出'(' } // 如果是运算符 else if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/') { while (!isEmptyOp(&ops) && peekOp(&ops) != '(' && precedence(peekOp(&ops)) >= precedence(expr[i])) { char op = popOp(&ops); int b = popNum(&nums); int a = popNum(&nums); switch(op) { case '+': pushNum(&nums, a + b); break; case '-': pushNum(&nums, a - b); break; case '*': pushNum(&nums, a * b); break; case '/': pushNum(&nums, a / b); break; } } pushOp(&ops, expr[i]); } } // 处理剩余运算符 while (!isEmptyOp(&ops)) { char op = popOp(&ops); int b = popNum(&nums); int a = popNum(&nums); switch(op) { case '+': pushNum(&nums, a + b); break; case '-': pushNum(&nums, a - b); break; case '*': pushNum(&nums, a * b); break; case '/': pushNum(&nums, a / b); break; } } return popNum(&nums);}int main() { char expr[100]; printf("请输入一个表达式(支持+ - * / 和括号):\n"); fgets(expr, sizeof(expr), stdin); expr[strcspn(expr, "\n")] = 0; // 去掉换行符 int result = evaluate(expr); printf("结果是:%d\n", result); return 0;}precedence() 函数判断 * / 的优先级高于 + -。运行程序后,输入以下表达式:
(3 + 5) * 2 - 10 / 2
输出结果应为:
结果是:11
通过这个项目,你不仅掌握了 C语言表达式求值 的核心算法,还深入理解了栈在实际问题中的应用。这也是面试中常见的编程题之一。
如果你希望扩展功能(如支持小数、负数、更多函数),可以在当前框架上继续开发。记住,后缀表达式计算 是很多高级计算器和编译器的基础技术。
现在,你已经拥有了一个自己动手实现的 C语言栈式计算器!快去试试不同的表达式吧!
本文由主机测评网于2025-12-11发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025125966.html