使用C語言與棧實現簡單多則運算計算器(包括括號優先順序運算)
阿新 • • 發佈:2019-01-03
#include <stdio.h> #include <stdlib.h> #define MAX 20 //定義第一個棧---作為存放運算數的操作符 struct SNode_Num { int datas[MAX]; int top; }; typedef struct SNode_Num OperateNum; //定義第二個棧---作為存放運算子號的棧 struct SNode_Symbol { char symbol[MAX]; int top; }; typedef struct SNode_Symbol OperateSymbol; /******************************************************************** 描述:定義函式:InitOperandNum,並且初始化運算數棧頂 引數:OperateNum *StackNum 返回值:void ********************************************************************/ void InitOperateNum(OperateNum *StackNum) { StackNum->top = -1; } /******************************************************************** 描述:定義函式: InitOperateSymbol,並且初始化運算子棧頂 引數:OperateSymbol *StackSymbol 返回值:void ********************************************************************/ void InitOperateSymbol(OperateSymbol *StackSymbol) { StackSymbol->top = -1; } /******************************************************************** 描述:定義函式:PushOperateNum, 壓一個數到棧頂 引數:OperateNum *StackNum, int x 返回值:void ********************************************************************/ void PushOperateNum(OperateNum *StackNum, int x) { StackNum->top++; StackNum->datas[StackNum->top] = x; } /******************************************************************** 描述:定義函式:PushOperateSymbol,壓一個運算子到棧頂 引數:OperateSymbol *StackSymbol, char ch 返回值:void ********************************************************************/ void PushOperateSymbol(OperateSymbol *StackSymbol, char ch) { StackSymbol->top++; StackSymbol->symbol[StackSymbol->top] = ch; } /******************************************************************** 描述:定義函式:PopOperateNum,將運算數從棧中讀取出來 引數:OperateNum *StackNum 返回值:返回取出來的數 ********************************************************************/ int PopOperateNum(OperateNum *StackNum) { int num; num = StackNum->datas[StackNum->top]; StackNum->top--; return num; } /******************************************************************** 描述:定義函式:PopOperateSymbol,將運算子從棧中取出來 引數:OperateSymbol *StackSymbol 返回值:返回取出來的符號 ********************************************************************/ char PopOperateSymbol(OperateSymbol *StackSymbol) { char ch; ch = StackSymbol->symbol[StackSymbol->top]; StackSymbol->top--; return ch; } //取出相應的數 int GetOperateNum(OperateNum *StackNum) { return StackNum->datas[StackNum->top]; } //取出相應運算子 char GetOperateSymbol(OperateSymbol *StackSymbol) { return StackSymbol->symbol[StackSymbol->top]; } /******************************************************************** 描述:定義函式, IsOperateSymbolOrNum,判斷輸入的符號是那些符號 引數:char ch 返回值:有符號返回1,無符號返回0 ********************************************************************/ short IsOperateSymbolOrNum(char ch) { //判斷所有需要用的操作符 包括 + - * / ( ) \n if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '\n') return 1; else return 0; } /******************************************************************** 描述:定義函式: Priority,用於判斷符號優先順序運算 引數:char inputnum, char ch 返回值:符號的大小的字元 ********************************************************************/ char Priority(char inputnum, char ch) { switch(inputnum) { //加減在同一個優先順序上 case '+': case '-': { if(ch == '+' || ch == '-') return '>'; else if(ch == '*' || ch == '/') return '<'; else if(ch == '(') return '<'; else if(ch == ')') return '>'; else return '>'; } break; //乘除在同一優先順序 case '*': case '/': { if(ch == '+' || ch == '-') return '>'; else if(ch == '*' || ch == '/') return '>'; else if(ch == '(') return '<'; else if(ch == ')') return '>'; else return '>'; } break; //括號在所有優先順序以上 case '(': { if(ch == ')') return '='; else return '<'; } break; case ')': { return '>'; } break; case '\n': { if(ch == '\n') return '='; else return '<'; } break; } } /******************************************************************** 描述:定義函式: Calculate,計算結果 引數:int num1, char ch, int num2 返回值:返回兩個數計算的結果result ********************************************************************/ int Calculate(int num1, char ch, int num2) { int result; switch(ch) { case '+': result = num1 + num2; break; case '-': result = num1 - num2; break; case '*': result = num1 * num2; break; case '/': result = num1 / num2; } return result; } /******************************************************************** 描述:定義函式:MainCalc,主要用於獲取使用者輸入,並且進行計算 引數:void 返回值:result ********************************************************************/ int MainCalc() { //主函式進行計算 OperateNum datas; OperateSymbol symbol; int num1, num2, result, num; char ch, sign; InitOperateNum(&datas); InitOperateSymbol(&symbol); //把回車計算的操作符放在棧中 PushOperateSymbol(&symbol, '\n'); ch = getchar(); while((ch != '\n') || (GetOperateSymbol(&symbol) != '\n')) { if(!IsOperateSymbolOrNum(ch)) { num = atoi(&ch); //將字元轉換為整數 ch = getchar(); //獲取輸入 while(!IsOperateSymbolOrNum(ch)) { num = num * 10 + atoi(&ch); ch = getchar(); //當沒有輸入回車時,繼續獲取輸入 } PushOperateNum(&datas, num); } else { switch(Priority(GetOperateSymbol(&symbol), ch)) { //判斷優先順序後進行計算 case '<': PushOperateSymbol(&symbol, ch); ch = getchar(); break; case '=': sign = PopOperateSymbol(&symbol); ch = getchar(); //獲取輸入 break; case '>': sign = PopOperateSymbol(&symbol); num2 = PopOperateNum(&datas); num1 = PopOperateNum(&datas); result = Calculate(num1, sign, num2); PushOperateNum(&datas, result); break; } } } result = GetOperateNum(&datas); return result; } int main(int argc, char *argv[]) { int result; result = MainCalc(); printf("%d", result); //輸出結果 return 0; }
歡迎關注我的個人Blog:[我的blog](https://www.finen.top)