1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <conio.h>
4
5 #define _CRT_SECURE_NO_WARNINGS//解决vs下直接用scanf报错
6
7 typedef struct operandstack//操作数栈
8 {
9 int Operand;//操作数
10 struct operandstack* Next;
11 }OPERAND;
12
13 typedef struct operatorstack//运算符栈
14 {
15 char Operator;//运算符
16 struct operatorstack* Next;
17 }OPERATOR;
18
19 int Is(char temp);//temp是操作数返回1,否则返回0
20 void Push_operand(OPERAND* operand_top, int number);//操作数入栈
21 void Push_operator(OPERATOR* operator_top, char temp);//运算符入栈
22 int Pop_operand(OPERAND* operand_top);//操作数出栈
23 char Pop_operator(OPERATOR* operator_top);//运算符出栈
24 char Precede(char temp1, char temp2);//temp1高优先级就输出‘>',同优先级输出'=', 低优先级输出 '<'
25 int Operate(int a, char theta, int b);//返回二元运算 a theta b 的结果
26
27 int main(void)
28 {
29 char temp = NULL;//输入的字符
30 int number = 0;//字符转换成操作数
31 int value = 0;//表达式的值
32 int a = 0;//a theta b
33 int b = 0;
34 char theta = NULL;//二元运算的运算符
35 OPERAND* operand_top = (OPERAND*)calloc(1, sizeof(OPERAND));//操作数栈顶
36 OPERATOR* operator_top = (OPERATOR*)calloc(1, sizeof(OPERATOR));//运算符栈顶
37 OPERAND* operand_s = NULL;//指向操作数栈的指针
38 OPERATOR* operator_s = NULL;//指向运算符栈的指针
39 operand_top->Next = NULL;//初始化操作数栈
40 operator_top->Next = NULL;//初始化运算符栈
41
42 Push_operator(operator_top, '=');//把‘=’压入运算符栈底
43
44 printf("请输入表达式(以=号结尾):");//表达式求值
45 temp = getchar();//读取首个输入
46 printf("\n************************************\n");
47 while (temp != '=' || operator_top->Next->Operator != '=')//输入为‘=’且运算符栈中仅有‘=’时退出循环
48 {
49 if (temp == ' ')//忽略空格
50 {
51 do
52 {
53 temp = getchar();
54 } while (temp == ' ');
55 }
56 else if (Is(temp) == 1)//temp是操作数返回1,否则返回0
57 {
58 printf("\n%c是操作数!", temp);
59 number = temp - '0';
60 temp = getchar();//读取下一个输入
61 while (Is(temp) && temp != ' ')//如果下一个输入还是数字,说明这是同一个操作数
62 {
63 number = 10 * number + (temp - '0');//同一个操作数的不同位
64 temp = getchar();
65 }
66 Push_operand(operand_top, number);//把操作数压入操作数栈
67 printf("\n操作数%d进栈了!", number);
68 }//if是操作数
69 else//temp是运算符
70 {
71 printf("\n%c是运算符!", temp);
72 printf("\n正在比较输入%c和栈顶运算符%c优先级!", temp, operator_top->Next->Operator);
73
74 switch (Precede(temp, operator_top->Next->Operator))//比较优先级
75 {
76 case '>'://temp优先级高
77 printf("\n运算符%c进栈了!", temp);
78 Push_operator(operator_top, temp);//运算符压入栈
79 temp = getchar();
80 break;
81 case '='://两者优先级相同
82 Pop_operator(operator_top);
83 temp = getchar();
84 break;
85 case '<'://temp优先级低
86 //将出栈的两个操作数及运算符进行二元运算,运算结果压入操作数栈
87 value = Operate(Pop_operand(operand_top) , Pop_operator(operator_top), Pop_operand(operand_top));
88 printf("\n二元运算的值为:%d", value);
89 printf("\n操作数%d进栈了!", value);
90 Push_operand(operand_top, value);//运算结果压入栈
91 break;
92 default:
93 printf("\n优先级错误!");
94 exit(-1);
95 }//switch
96 }//else
97 }//while
98
99 if (operand_top->Next == NULL)//操作数栈中没有操作数报错
100 {
101 printf("\n表达式求值错误!");
102 exit(-1);
103 }
104 printf("\n\n************************************\n");
105 printf("\n表达式的值为%d\n", operand_top->Next->Operand);
106 printf("\n************************************\n");
107 system("pause");
108 return 0;
109 }
110
111 int Is(char temp)//temp是操作数返回1,是运算符返回0
112 {
113 char a[7] = { '+', '-', '*', '/', '(', ')', '=' };//运算符
114 int i;
115 if (temp >= '0' && temp <= '9')
116 {
117 return 1;
118 }
119 for (i = 0; a[i] != '\0'; i++)
120 {
121 if (a[i] == temp)
122 {
123 return 0;
124 }
125 }
126 printf("\n输入的既不是操作数也不是操作符!");
127 exit(-1);
128 }
129
130 void Push_operand(OPERAND* operand_top, int number)//把操作数压入操作数栈
131 {
132 OPERAND* operand_s;
133 if ((operand_s = (OPERAND*)calloc(1, sizeof(OPERAND))) == NULL)
134 {
135 printf("\nclear allocation fail !");
136 exit(-1);
137 }
138 operand_s->Operand = number;
139 operand_s->Next = operand_top->Next;
140 operand_top->Next = operand_s;
141 }
142
143 void Push_operator(OPERATOR* operator_top, char temp)//把运算符压入运算符栈
144 {
145 OPERATOR* operator_s;
146 if ((operator_s = (OPERATOR*)calloc(1, sizeof(OPERATOR))) == NULL)//把‘=’压入栈底
147 {
148 printf("\nclear allocation fail !");
149 exit(-1);
150 }
151 operator_s->Operator = temp;
152 operator_s->Next = operator_top->Next;
153 operator_top->Next = operator_s;
154 }
155
156 int Pop_operand(OPERAND* operand_top)//操作数出栈
157 {
158 int temp;
159 OPERAND* p;
160 p = operand_top->Next;
161 temp = p->Operand;
162 operand_top->Next = p->Next;
163 free(p);
164 //printf("\n返回%d", temp);
165 return temp;
166 }
167
168 char Pop_operator(OPERATOR* operator_top)//操作符出栈
169 {
170 char temp;
171 OPERATOR* p;
172 if (operator_top->Next == NULL)
173 {
174 printf("\n空栈!");
175 exit(-1);
176 }
177 p = operator_top->Next;
178 temp = p->Operator;
179 operator_top->Next = p->Next;
180 free(p);
181 return temp;
182 }
183
184 char Precede(char temp1, char temp2)//比较优先级,temp1高优先级就输出‘>',同优先级输出'=',temp1低优先级输出 '<'
185 {
186 switch (temp1)
187 {
188 case '+':
189 case '-':
190 switch (temp2)
191 {
192 case '(':
193 case '=':
194 return '>';
195 break;
196 case '+':
197 case '-':
198 case '*':
199 case '/':
200 case ')':
201 return '<';
202 break;
203 default:
204 printf("\n优先级比较错误!");
205 exit(-1);
206 }
207 case '*':
208 case '/':
209 switch (temp2)
210 {
211 case '+':
212 case '-':
213 case '=':
214 case '(':
215 return '>';
216 break;
217 case '*':
218 case '/':
219 case ')':
220 return '<';
221 break;
222 default:
223 printf("\n优先级比较错误!");
224 exit(-1);
225 }
226 case '(':
227 switch (temp2)
228 {
229 case '+':
230 case '-':
231 case '*':
232 case '/':
233 case '(':
234 return '>';
235 break;
236 default:
237 printf("\n优先级比较错误!");
238 exit(-1);
239 }
240 case ')':
241 switch (temp2)
242 {
243 case '+':
244 case '-':
245 case '*':
246 case '/':
247 return '<';
248 break;
249 case '(':
250 return '=';
251 break;
252 default:
253 printf("\n优先级比较错误!");
254 exit(-1);
255 }
256 case '=':
257 switch (temp2)
258 {
259 case '+':
260 case '-':
261 case '*':
262 case '/':
263 case '(':
264 return '<';
265 break;
266 case '=':
267 return '=';
268 break;
269 default:
270 printf("\n优先级比较错误!");
271 exit(-1);
272 }
273 default:
274 printf("\n优先级比较错误!");
275 exit(-1);
276 }
277 }
278
279 int Operate(int a, char theta, int b)//返回二元运算 a theta b 的结果
280 {
281 switch (theta)
282 {
283 case '+':
284 return a + b;
285 break;
286 case '-':
287 return a - b;
288 break;
289 case '*':
290 return a * b;
291 break;
292 case '/':
293 if (b == 0)
294 {
295 printf("\n分母不能为0!");
296 exit(-1);
297 }
298 return a / b;
299 break;
300 default:
301 printf("\n二元运算错误!");
302 exit(-1);
303 }
304 }