C语言计算器
Created Jun 18, 2025 - Last updated: Jun 18, 2025
Evergreen 🌳
数据结构
栈实现
#include <ctype.h>
#include <stdio.h>
#define MAX 100
typedef struct {
double data[MAX];
int top;
} Stack;
void push(Stack* s, double val)
{
s->data[++s->top] = val;
}
double pop(Stack* s)
{
return s->data[s->top--];
}
char top(Stack* s)
{
return s->data[s->top];
}
int precedence(char op)
{
if (op == '+' || op == '-')
return 1;
if (op == '*' || op == '/')
return 2;
return 0;
}
int isOperator(char ch)
{
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
void infixToPostfix(char* expr, char* postfix)
{
Stack stack;
stack.top = -1;
int i = 0, j = 0;
while (expr[i] != '=') {
if (isdigit(expr[i])) {
while (isdigit(expr[i])) {
postfix[j++] = expr[i++];
}
postfix[j++] = ' ';
} else if (expr[i] == '(') {
push(&stack, expr[i++]);
} else if (expr[i] == ')') {
while (top(&stack) != '(')
postfix[j++] = pop(&stack);
pop(&stack);
i++;
} else if (isOperator(expr[i])) {
while (stack.top != -1 && precedence(top(&stack)) >= precedence(expr[i]))
postfix[j++] = pop(&stack);
push(&stack, expr[i++]);
} else {
i++;
}
}
while (stack.top != -1)
postfix[j++] = pop(&stack);
postfix[j] = '\0';
}
double evalPostfix(char* postfix)
{
Stack stack;
stack.top = -1;
int i = 0;
while (postfix[i]) {
if (isdigit(postfix[i]) || postfix[i] == '.') {
double val;
sscanf(&postfix[i], "%lf", &val);
push(&stack, val);
while (isdigit(postfix[i]) || postfix[i] == '.')
i++;
} else if (isOperator(postfix[i])) {
double b = pop(&stack);
double a = pop(&stack);
switch (postfix[i]) {
case '+':
push(&stack, a + b);
break;
case '-':
push(&stack, a - b);
break;
case '*':
push(&stack, a * b);
break;
case '/':
push(&stack, a / b);
break;
}
i++;
} else {
i++;
}
}
return pop(&stack);
}
int main(void)
{
char expr[MAX], postfix[MAX];
fgets(expr, MAX, stdin);
infixToPostfix(expr, postfix);
double result = evalPostfix(postfix);
printf("%.2lf\n", result);
return 0;
}
二叉树实现
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum {
NUMBER,
OPERATOR
} NodeType;
typedef struct Node {
NodeType type; // 节点类型:数值或运算符
union {
int number; // 存储数值
char op; // 存储运算符('+', '-', '*', '/')
} value;
struct Node* left; // 左子节点
struct Node* right; // 右子节点
} Node, *Nodeptr;
typedef struct stack_node {
Nodeptr node;
struct stack_node* next;
} stack_node;
typedef struct {
stack_node* top;
} stack;
void stack_init(stack* s)
{
s->top = NULL;
}
void stack_push(stack* s, const Nodeptr val)
{
stack_node* n = malloc(sizeof(stack_node));
n->node = val;
n->next = s->top;
s->top = n;
}
Nodeptr stack_pop(stack* s)
{
if (!s->top)
return NULL;
stack_node* temp = s->top;
Nodeptr result = temp->node;
s->top = temp->next;
free(temp);
return result;
}
bool stack_is_empty(const stack* s)
{
return s->top == NULL;
}
Nodeptr stack_peek(const stack* s)
{
return s->top ? s->top->node : NULL;
}
void stack_destroy(stack* s)
{
while (!stack_is_empty(s))
free(stack_pop(s));
}
#define MAX 100
typedef struct {
int data[MAX];
int top;
} Stack;
void push(Stack* s, int val)
{
s->data[++s->top] = val;
}
int pop(Stack* s)
{
return s->data[s->top--];
}
char top(Stack* s)
{
return s->data[s->top];
}
int precedence(char op)
{
if (op == '+' || op == '-')
return 1;
if (op == '*' || op == '/')
return 2;
return 0;
}
int isOperator(char ch)
{
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
void infixToPostfix(char* expr, char* postfix)
{
Stack stack;
stack.top = -1;
int i = 0, j = 0;
while (expr[i] != '=') {
if (isdigit(expr[i])) {
while (isdigit(expr[i])) {
postfix[j++] = expr[i++];
}
postfix[j++] = ' ';
} else if (expr[i] == '(') {
push(&stack, expr[i++]);
} else if (expr[i] == ')') {
while (top(&stack) != '(')
postfix[j++] = pop(&stack);
pop(&stack);
i++;
} else if (isOperator(expr[i])) {
while (stack.top != -1 && precedence(top(&stack)) >= precedence(expr[i]))
postfix[j++] = pop(&stack);
push(&stack, expr[i++]);
} else {
i++;
}
}
while (stack.top != -1)
postfix[j++] = pop(&stack);
postfix[j] = '\0';
}
int evalPostfix(char* postfix)
{
Stack stack;
stack.top = -1;
int i = 0;
while (postfix[i]) {
if (isdigit(postfix[i]) || postfix[i] == '.') {
int val;
sscanf(&postfix[i], "%d", &val);
push(&stack, val);
while (isdigit(postfix[i]) || postfix[i] == '.')
i++;
} else if (isOperator(postfix[i])) {
int b = pop(&stack);
int a = pop(&stack);
switch (postfix[i]) {
case '+':
push(&stack, a + b);
break;
case '-':
push(&stack, a - b);
break;
case '*':
push(&stack, a * b);
break;
case '/':
push(&stack, a / b);
break;
}
i++;
} else {
i++;
}
}
return pop(&stack);
}
Nodeptr postfix_to_tree(char* postfix)
{
stack stack;
stack_init(&stack);
int len = strlen(postfix);
int i = 0;
while (i < len) {
Nodeptr newnode = (Nodeptr)malloc(sizeof(Node));
if (isdigit(postfix[i])) {
int num = postfix[i++] - '0';
while (isdigit(postfix[i])) {
num = num * 10 + (postfix[i++] - '0');
}
newnode->type = NUMBER;
newnode->value.number = num;
newnode->left = NULL;
newnode->right = NULL;
stack_push(&stack, newnode);
} else if (isOperator(postfix[i])) {
newnode->type = OPERATOR;
newnode->value.op = postfix[i];
Nodeptr right = stack_peek(&stack);
stack_pop(&stack);
Nodeptr left = stack_peek(&stack);
stack_pop(&stack);
newnode->left = left;
newnode->right = right;
stack_push(&stack, newnode);
i++;
} else {
i++;
}
}
return stack_peek(&stack);
}
int evalPostfixt(Nodeptr root)
{
if (root->left == NULL && root->right == NULL) {
return root->value.number;
} else {
if (root->type == OPERATOR) {
switch (root->value.op) {
case '+':
return evalPostfixt(root->left) + evalPostfixt(root->right);
break;
case '-':
return evalPostfixt(root->left) - evalPostfixt(root->right);
break;
case '*':
return evalPostfixt(root->left) * evalPostfixt(root->right);
break;
case '/':
return evalPostfixt(root->left) / evalPostfixt(root->right);
break;
}
}
}
return 0;
}
int main(void)
{
char expr[MAX], postfix[MAX];
fgets(expr, MAX, stdin);
infixToPostfix(expr, postfix);
Nodeptr root = postfix_to_tree(postfix);
if (root != NULL) {
(root->type == NUMBER) ? printf("%d", root->value.number) : printf("%c", root->value.op);
}
if (root->left != NULL) {
(root->left->type == NUMBER) ? printf(" %d", root->left->value.number) : printf(" %c", root->left->value.op);
}
if (root->right != NULL) {
(root->right->type == NUMBER) ? printf(" %d", root->right->value.number) : printf(" %c", root->right->value.op);
}
printf("\n");
int ans = evalPostfixt(root);
printf("%d\n", ans);
return 0;
}