慕九州9493288 的学生作业:
一、代码
linkstack.h
#ifndef __LINKSTACK_H__
#define __LINKSTACK_H__
// 定义栈存储的数据类型(操作数为int,运算符为ASCII码)
typedef int datatype_t;
// 栈节点结构体
typedef struct linknode {
datatype_t data;
struct linknode *next;
} linknode_t;
// 栈结构体(链式栈)
typedef struct linkstack {
linknode_t *top; // 栈顶指针
int n; // 栈中元素个数
} linkstack_t;
// 创建空栈
extern linkstack_t *create_empty_linkstack();
// 判断栈是否为空
extern int is_empty_linkstack(linkstack_t *s);
// 入栈操作
extern void push_linkstack(linkstack_t *s, datatype_t data);
// 出栈操作
extern datatype_t pop_linkstack(linkstack_t *s);
// 获取栈顶元素
extern datatype_t get_top_linkstack(linkstack_t *s);
// 销毁栈(释放所有资源)
extern void destroy_linkstack(linkstack_t *s);
#endif
linkstack.c
#include
#include
#include "linkstack.h"
// 创建空栈
linkstack_t *create_empty_linkstack() {
linkstack_t *s = (linkstack_t *)malloc(sizeof(linkstack_t));
if (NULL == s) {
printf("错误:栈结构体内存分配失败!\n");
return NULL;
}
s->top = NULL;
s->n = 0;
return s;
}
// 判断栈是否为空(空返回1,非空返回0)
int is_empty_linkstack(linkstack_t *s) {
if (NULL == s) return 1; // 空指针视为空栈
return (s->top == NULL) ? 1 : 0;
}
// 入栈操作
void push_linkstack(linkstack_t *s, datatype_t data) {
if (NULL == s) {
printf("错误:栈指针为空,无法入栈!\n");
return;
}
// 创建新节点
linknode_t *temp = (linknode_t *)malloc(sizeof(linknode_t));
if (NULL == temp) {
printf("错误:栈节点内存分配失败!\n");
return;
}
// 新节点入栈(头插法)
temp->data = data;
temp->next = s->top;
s->top = temp;
s->n++;
}
// 出栈操作(返回出栈元素,栈空时返回-1)
datatype_t pop_linkstack(linkstack_t *s) {
if (NULL == s) {
printf("错误:栈指针为空,无法出栈!\n");
return -1;
}
if (is_empty_linkstack(s)) {
printf("错误:栈为空,无法出栈!\n");
return -1;
}
// 保存栈顶节点信息
linknode_t *temp = s->top;
datatype_t data = temp->data;
// 移除栈顶节点
s->top = temp->next;
free(temp); // 释放节点内存
s->n--;
return data;
}
// 获取栈顶元素(不弹出,栈空时返回-1)
datatype_t get_top_linkstack(linkstack_t *s) {
if (NULL == s) {
printf("错误:栈指针为空,无法获取栈顶元素!\n");
return -1;
}
if (is_empty_linkstack(s)) {
printf("错误:栈为空,无法获取栈顶元素!\n");
return -1;
}
return s->top->data;
}
// 销毁栈(释放所有节点和栈结构体)
void destroy_linkstack(linkstack_t *s) {
if (NULL == s) return;
// 释放所有节点
while (!is_empty_linkstack(s)) {
pop_linkstack(s);
}
// 释放栈结构体
free(s);
}
arithmetic_operations.h
#ifndef __ARITHMETIC_OPERATIONS_H__
#define __ARITHMETIC_OPERATIONS_H__
#include "linkstack.h"
// 获取运算符优先级(数字越大优先级越高)
extern int get_level(char opt);
// 执行一次运算(返回0成功,1失败)
extern int compute(linkstack_t *opd, linkstack_t *opt);
// 处理运算符(包括括号)
extern void deal_with_operator(linkstack_t *opd, linkstack_t *opt, char current_op);
#endif
arithmetic_operations.c
#include
#include "arithmetic_operations.h"
#include "linkstack.h"
// 获取运算符优先级
int get_level(char opt) {
switch (opt) {
case '(': // 左括号优先级最低(用于控制入栈)
return 0;
case '+':
case '-': // 加减优先级1
return 1;
case '*':
case '/': // 乘除优先级2
return 2;
default: // 无效运算符
printf("错误:无效运算符 '%c'\n", opt);
return -1;
}
}
// 执行一次运算(从栈中取运算符和操作数)
int compute(linkstack_t *opd, linkstack_t *opt) {
if (is_empty_linkstack(opd) || is_empty_linkstack(opt)) {
printf("错误:栈数据不足,无法计算!\n");
return 1;
}
int data1 = 0, data2 = 0, result = 0;
char op = '\0';
// 弹出两个操作数(注意顺序:后弹出的是第一个操作数)
data2 = pop_linkstack(opd);
data1 = pop_linkstack(opd);
if (data1 == -1 || data2 == -1) { // 检查出栈是否成功
return 1;
}
// 弹出运算符
op = (char)pop_linkstack(opt);
if (op == -1) { // 检查运算符出栈是否成功
return 1;
}
// 执行运算
switch (op) {
case '+':
result = data1 + data2;
break;
case '-':
result = data1 - data2;
break;
case '*':
result = data1 * data2;
break;
case '/':
if (data2 == 0) { // 处理除数为0
printf("错误:除数不能为0!\n");
// 回滚操作数和运算符(恢复栈状态)
push_linkstack(opd, data1);
push_linkstack(opd, data2);
push_linkstack(opt, op);
return 1;
}
result = data1 / data2; // 整数除法
break;
default:
printf("错误:无法识别的运算符 '%c'\n", op);
return 1;
}
// 运算结果入栈
push_linkstack(opd, result);
return 0;
}
// 处理运算符(包括括号逻辑)
void deal_with_operator(linkstack_t *opd, linkstack_t *opt, char current_op) {
// 情况1:左括号 '(' → 直接入栈
if (current_op == '(') {
push_linkstack(opt, (int)current_op);
return;
}
// 情况2:右括号 ')' → 计算到左括号为止
if (current_op == ')') {
// 弹出运算符计算,直到遇到左括号
while (!is_empty_linkstack(opt)) {
char top_op = (char)get_top_linkstack(opt);
if (top_op == '(') { // 找到左括号,终止循环
pop_linkstack(opt); // 弹出左括号(不参与计算)
return;
}
// 计算栈顶运算符
if (compute(opd, opt) != 0) {
return; // 计算出错时退出
}
}
// 若循环结束仍未找到左括号,说明括号不匹配
printf("错误:括号不匹配(缺少左括号 '(')!\n");
return;
}
// 情况3:普通运算符(+、-、*、/)→ 按优先级处理
while (!is_empty_linkstack(opt)) {
char top_op = (char)get_top_linkstack(opt);
// 栈顶是左括号时,当前运算符直接入栈
if (top_op == '(') {
break;
}
// 当前运算符优先级 ≤ 栈顶运算符 → 先计算栈顶
if (get_level(current_op) = '0' && *p = '0' && *p n == 1) {
printf("计算结果:%d\n", pop_linkstack(opd_stack));
} else {
printf("错误:计算失败(结果异常)!\n");
}
// 释放资源
destroy_linkstack(opd_stack);
destroy_linkstack(opt_stack);
return 0;
}
二、结果
【图片】