称不上项目的小程序3:计算器

来源:互联网 发布:bp神经网络的java实现 编辑:程序博客网 时间:2024/06/14 09:56

这是用2个栈实现一个小计算器功能,包含的运算符有:+ , - ,  * ,  / ,  ( , ) ,可谓“功能强大”!

(这次可是很用心的加了很多注释的,好吧,是我之前的程序都没用心加)


1、calculatestack.h

#ifndef __CALCULATESTACK_H__#define __CALCULATESTACK_H__#define TRUE  1#define FALSE 0#define PUSH 1#define JISUAN 0#define SIZE 50typedef struct _num{int num[SIZE];    // 栈数组int top;          // 栈顶元素下标}Num;typedef struct _opt{char opt[SIZE];    int top;         }Opt;// 置空栈int InitStack_Opt (Opt *S); int InitStack_Num (Num *S); // 判断输入类型,数字返T,字符返Fint judge_type (char ch);// 进栈int Push_NUM (Num *s, int x);int Push_Opt (Opt *s, char ch);// 出栈int Pop_Num (Num *s, int *x); int Pop_Opt (Opt *s, char *ch);// 判断运算符是否进行计算int judge_op (Opt *s, char ch);// 计算int Jisuan (Num *s_num, Opt *s_opt);#endif // __CALCULATESTACK_H__

2、calculatestack.c

#include "calculateStack.h"// 置空栈int InitStack_Num (Num *S){if (S == NULL){errno = ERROR;return FALSE;}S->top = -1;return TRUE;}int InitStack_Opt (Opt *S){if (S == NULL){errno = ERROR;return FALSE;}S->top = -1;return TRUE;}// 判断输入类型int judge_type (char ch){if (ch >= '0' && ch <= '9')return TRUE;   // 数字返TRUEelsereturn FALSE;  // 字符返FALSE}// 进栈int Push_Num (Num *s, int x){// 判断是否满栈if (s->top == SIZE -1){errno = FULL_STACK;return FALSE;}else{s->num[++s->top] = x;return TRUE;}}int Push_Opt (Opt *s, char ch){// 判断是否满栈if (s->top == SIZE -1){errno = FULL_STACK;return FALSE;}else{s->opt[++s->top] = ch;return TRUE;}}// 出栈int Pop_Num (Num *s, int *x){// 判断是否空栈if (s->top == -1){errno = EMPTY_STACK;return FALSE;}*x = s->num[s->top--];  // x用来保存出栈的数字return TRUE;}int Pop_Opt (Opt *s, char *ch){// 判断是否空栈if (s->top == -1){errno = EMPTY_STACK;return FALSE;}*ch = s->opt[s->top--];  // ch用来保存出栈的字符return TRUE;}// 先计算再入栈int Jisuan (Num *s_num, Opt *s_opt){// 判断数字栈中是否还有2个数据if (s_num->top == 0){errno = ERROR;myError("s_num->top == 0");return FALSE;}// 判断字符栈中是否还有1个数据if (s_opt->top == -1){errno = EMPTY_STACK;myError("s_opt->top == -1");return FALSE;}int num1, num2, num3;Pop_Num (s_num, &num1);Pop_Num (s_num, &num2);  // 取出数据char ch;Pop_Opt (s_opt, &ch);    // 取出字符if (ch == '+') num3 = num2 + num1;else if (ch == '-')num3 = num2 - num1;else if (ch == '*')num3 = num2 * num1;else if (ch == '/'){if (num1 == 0){printf ("分母为0,错误\n");return FALSE;}elsenum3 = num2 / num1;}Push_Num (s_num, num3);  // 将计算结果入数字栈return TRUE;}// 判断运算符是否进行计算int judge_op (Opt *s, char ch){// 栈空或传入的字符为'('则直接进栈if (s->top == -1 || ch == '(')  {return PUSH;}else{switch (s->opt[s->top]){case '+':case '-':if (ch == '+' || ch == '-')  // 栈顶为'+','-'时return JISUAN; // 加减需计算elsereturn PUSH;             // 其他全进栈break;case '*':case '/':return JISUAN; // 栈顶为'*','/'时全部进计算break;case '(':return PUSH; // 栈顶为'(' 全部进栈break;}}}
3、main.c
#include <stdio.h>#include <stdlib.h>#include "calculateStack.h"int main(){Num s_num;Opt s_opt;if (InitStack_Num(&s_num) == FALSE){printf ("errno:%d\n", errno);char * a = myStrError(errno);printf ("a: %s\n", a);}if (InitStack_Opt(&s_opt) == FALSE){printf ("errno:%d\n", errno);char * a = myStrError(errno);printf ("a: %s\n", a);}char a[SIZE];     // 临时存放用来转化为数字的字符串char str[SIZE];printf ("请输入算式:");scanf ("%s",str);getchar();int i = 0;while (str[i] != '\0'){// 判断输入的是否为数字if (judge_type (str[i]) == TRUE){int j = 0;while (judge_type (str[i]) == TRUE)    // 判断接下来的字符是否为数字{a[j++] = str[i];                 i++;}a[j] = '\0';i--;Push_Num (&s_num, atoi(a));            // 数字进栈}else {if (str[i] == ')')         // 如果进来的字符是')'则计算至'('{while (s_opt.opt[s_opt.top] != '('){Jisuan(&s_num, &s_opt);}char ch1[SIZE] = {0};Pop_Opt (&s_opt, ch1);   // 左括号出栈}//  判断进栈还是计算else if (judge_op (&s_opt, str[i]) == PUSH) {Push_Opt (&s_opt, str[i]);}else{Jisuan (&s_num, &s_opt);    // 计算上一个字符Push_Opt (&s_opt, str[i]);  // 此字符进栈}}i++;}while (s_opt.top != -1)       // 将栈中存放的字符全部计算掉{Jisuan (&s_num, &s_opt);}if (s_num.top != 0)           // 若数字栈中不是存放了一个结果则输入有误{printf ("输入格式错误!\n");}else{printf ("答案是:%d\n",s_num.num[s_num.top]);}return 0;}

原创粉丝点击