热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C语言利用前缀表达式实现复杂科学计算器

用C语言实现的科学计算器,支持2种常量,10种基本函数,Ans寄存器。相对来说拓展性应该是不错的,思路是首先化简复杂名称的函

用C语言实现的科学计算器,支持2种常量,10种基本函数,Ans寄存器。相对来说拓展性应该是不错的,思路是首先化简复杂名称的函数名和常量名,然后把表达式转换成前缀表达式,再直接处理前缀表达式即可。因此对运算符和括号优先级的处理比较容易完美实现,执行效率也比较高,且无论输入表达式有多么复杂,只要确保输入缓冲区(定义在Analytic.h中)够大后面的都好说。


Analytic.c 运算库源文件,考虑到了移植方便的问题:

//Create Date: 2018-3-4
//Author: Charming
//File: Analytic.c
//Version: 1.7.2
//Last edit Date: 2018-3-13
//Directions: 表达式解析库源文件
// v1.0.0: 基本前缀表达式转换
// v1.1.0: 支持区分正负号与加减运算符的功能
// v1.2.0: 新增额外的多字节函数化简,并支持转换相应的前缀表达式
// v1.3.0: 新增支持符号常量参与表达式转换
// v1.3.5: 区分正负号与加减运算符功能的完善
// v1.4.0: 增加计算功能
// v1.5.0: 增加函数计算功能
// v1.6.0: 增加常数项功能
// v1.6.2: 增强表达式错误辨别能力
// v1.6.5: 提高常数精度
// v1.7.0: 新增三角函数的预期计算结果趋近于0或者不存在时的单独处理功能
// v1.7.2: 优化常数项遇到负号时的计算问题
// v1.7.7: 解决单目运算符计算顺序的Bug#include "Analytic.h"
#include
#include char *Expression = 0;//中缀表达式指针
a_size_t E_Ptr = 0;//中缀表达式操作位置标记 char *Polish_Notation = 0;//前缀表达式指针
a_size_t P_Ptr = 0;//前缀表达式操作位置标记 double Calc_ANS = 0;//答案寄存器 /*基本常数项(数值)Start*/
const_mode double _const_Euler_ = 2.718281828459045;//自然常数e
const_mode double _const_Pai_ = 3.141592653589793;//圆周率π /*基本常数项(数值)End*//*基本常数项(符号)Start*/
const_mode char Ans[] = "Ans";//上一运算答案
#define S_Ans 'A'
const_mode char Pai[] = "Pai";//圆周率π的多字节符号
#define S_Pai 'P'
const_mode char Euler[] = "_e_";//自然常数,一般都使用e而不是_e_, //复杂名的写法仅为避免名称重复陷入死循环, //实际使用时直接用e即可
#define S_Euler 'e' /*基本常数项(符号)End*//*基本函数项Start*/
const_mode char Ln[] = "ln";//自然对数
#define S_In 'I'
const_mode char Exp[] = "Exp";//自然指数
#define S_Exp 'E'
const_mode char Log[] = "log";//以10为底的对数
#define S_Log 'L'
const_mode char Sin[] = "Sin";//正弦函数
#define S_Sin 's'
const_mode char Cos[] = "Cos";//余弦函数
#define S_Cos 'c'
const_mode char Tan[] = "Tan";//正切函数
#define S_Tan 't'
const_mode char Sqrt[] = "Sqrt";//开方函数
#define S_Sqrt 'Q'
const_mode char ArcSin[] = "Arcsin";//反正弦函数
#define S_ArcSin 'S'
const_mode char ArcCos[] = "Arccos";//反余弦函数
#define S_ArcCos 'C'
const_mode char ArcTan[] = "Arctan";//反正切函数
#define S_ArcTan 'T' /*基本函数项End*/const_mode char *ComplexOperators[] = {//多字节函数名列表,顺序从长到短,有利于逻辑实别 ArcSin, ArcCos, ArcTan, Exp, Log, Sin, Cos, Tan, Sqrt, Ln
};const_mode char SimpleOperators[] = {//单字节函数名列表,与多字节顺序需一一对应 S_ArcSin, S_ArcCos, S_ArcTan, S_Exp, S_Log, S_Sin, S_Cos, S_Tan,S_Sqrt, S_In
};const_mode char *ComplexConstants[] = {//多字节常量名列表,顺序从长到短,有利于逻辑实别 Ans, Pai, Euler
};const_mode char SimpleConstants[] = {//单字节常量名列表,与多字节顺序需一一对应 S_Ans, S_Pai, S_Euler
};struct {char data[SymbolMax];w_size_t top;
}Symbol_Stack;//运算符栈 struct {double data[NumberMax];w_size_t top;
}Number_Stack;//运算符栈 typedef enum
{Symbol, Number
}Stack_type;//栈类型 typedef enum
{isNumber,isNumberOrDot,isBrackets,isBracketLeft,isBracketRight,isOperatorsLevel3,isOperatorsLevel2,isOperatorsLevel1,isOperatorsLevel0,isConstants
}Symbol_type;//符号类型 void Init_Stack(Stack_type type)//堆栈初始化
{switch (type){case Symbol:Symbol_Stack.top = -1;break;case Number:Number_Stack.top = -1;break;default:break;}
}Analytic_type Symbol_Push(void)//中缀表达式中的当前字符入栈
{if (Symbol_Stack.top }Analytic_type Symbol_Pop(void)//从运算符栈出栈到前缀表达式
{if (Symbol_Stack.top >= 0)Polish_Notation[++P_Ptr] = Symbol_Stack.data[Symbol_Stack.top--];elsereturn Conv_Exception;return Conv_Ok;
}w_size_t Get_StringLen(char *str, const w_size_t Maxlen)//计算表达式长度
{
#if USESTRINGLIB == 0 w_size_t len = 0;while (str[len] != '\0' && len #else return (w_size_t)strnlen(str, Maxlen);
#endif
}#if STRINGLIB_standard == 1
char* my_strrev(char* s)
{char* h = s;char* t = s;char ch;while (*t++) {};t -= 2;//与t++抵消、回跳过结束符'\0' while (h }
#endif void Make_String_Reverse(char *str, const w_size_t Maxlen)//字符串反转
{w_size_t len;len = Get_StringLen(str, Maxlen);if (str[len - 1] == ' '){str[len - 1] = 0;}
#if STRINGLIB_standard == 1 my_strrev(str);
#else strrev(str);
#endif
}unsigned char Check(char *chr, Symbol_type type)//判断字符或字符串的类型
{a_size_t i;switch (type){case isNumber:if (*chr >&#61; &#39;0&#39; && *chr <&#61; &#39;9&#39;)return 1;break;case isNumberOrDot:if (*chr >&#61; &#39;0&#39; && *chr <&#61; &#39;9&#39; || *chr &#61;&#61; &#39;.&#39;)return 1;break;case isBrackets:if (*chr &#61;&#61; &#39;(&#39; || *chr &#61;&#61; &#39;)&#39;)return 1;break;case isBracketLeft:if (*chr &#61;&#61; &#39;(&#39;)return 1;break;case isBracketRight:if (*chr &#61;&#61; &#39;)&#39;)return 1;break;case isOperatorsLevel0:for (i &#61; 0; i }Analytic_type Convert_to_Polish(void)//中缀表达式到前缀表达式的转换程序
{Analytic_type AnserReg;unsigned char tempflag;P_Ptr &#61; -1;Init_Stack(Symbol);E_Ptr &#61; (a_size_t)Get_StringLen(Expression, Exprlen);while (E_Ptr >&#61; 0)//逆序处理 {if (Check(&Expression[E_Ptr], isNumber))//处理数值情况 {tempflag &#61; 0;//这里tempflag用于处理一个特殊情况(见下面代码)&#xff0c; //使用goto容易造成复杂的意外情况&#xff0c;因此改用单独设立的标志位和死循环配合实现 while (1){while (tempflag &#61;&#61; 1 || (E_Ptr >&#61; 0) && Check(&Expression[E_Ptr], isNumberOrDot)){tempflag &#61; 0;Polish_Notation[&#43;&#43;P_Ptr] &#61; Expression[E_Ptr--];//将数值或小数点转入前缀表达式 }if ((E_Ptr >&#61; 0) && //中缀表达式中还有没处理的 ((E_Ptr &#61;&#61; 0 && Check(&Expression[E_Ptr], isOperatorsLevel3)) ||Check(&Expression[E_Ptr], isOperatorsLevel3) &&!(Check(&Expression[E_Ptr - 1], isNumber) || Check(&Expression[E_Ptr - 1], isConstants)) &&!Check(&Expression[E_Ptr - 1], isBracketRight)))//由于三级运算符(&#39;&#43;&#39; &#39;-&#39;)可做正负号使用&#xff0c;因此对单独存在的三级运算符当做数的一部分处理&#xff0c; //即如果当前字符是最后一个字符&#xff0c;且是三级运算符&#xff0c;或者这并不是最后一个字符&#xff0c;且下一个字符 //不是右括号、不是数字或常量的情况下&#xff0c;这个三级运算符需要当作数处理。 tempflag &#61; 1;elsebreak;}Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//前缀表达式添加空格分隔符 }else if (Check(&Expression[E_Ptr], isConstants))//待处理的是常量 {Polish_Notation[&#43;&#43;P_Ptr] &#61; Expression[E_Ptr--];//将常量符号转入前缀表达式 if ((E_Ptr >&#61; 0) && //中缀表达式中还有没处理的 ((E_Ptr &#61;&#61; 0 && Check(&Expression[E_Ptr], isOperatorsLevel3)) ||Check(&Expression[E_Ptr], isOperatorsLevel3) &&!(Check(&Expression[E_Ptr - 1], isNumber) || Check(&Expression[E_Ptr - 1], isConstants)) &&!Check(&Expression[E_Ptr - 1], isBracketRight)))//对符号单独处理&#xff0c;原理类似于常数的处理方法 Polish_Notation[&#43;&#43;P_Ptr] &#61; Expression[E_Ptr--];//将常量符号转入前缀表达式 Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//前缀表达式添加空格分隔符 }else if (Check(&Expression[E_Ptr], isBracketRight))//待处理的字符是右括号 {if ((AnserReg &#61; Symbol_Push()) !&#61; Conv_Ok)//压入运算符栈&#xff0c;如果异常&#xff0c;则返回异常情况&#xff0c;压栈过程同时E_Ptr也移动&#xff0c;不需要重复操作 return AnserReg;}else if (Check(&Expression[E_Ptr], isBracketLeft))//待处理的字符是左括号 {while (!Check(&Symbol_Stack.data[Symbol_Stack.top], isBracketRight))//如果运算符栈栈顶不是右括号 {if ((AnserReg &#61; Symbol_Pop()) !&#61; Conv_Ok)//运算符出栈 return AnserReg;Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//出一次加一个空格 }Symbol_Stack.data[Symbol_Stack.top--] &#61; &#39;\0&#39;;//封栈&#xff0c;删除栈顶外内容 E_Ptr--;//处理下一位 }else if (Check(&Expression[E_Ptr], isOperatorsLevel3))//待处理字符是&#39;&#43;&#39;或&#39;-&#39; {while (Symbol_Stack.top >&#61; 0 &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel3) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isBracketRight))//运算符栈非空&#xff0c;且栈顶不是&#39;)&#39; &#39;&#43;&#39; &#39;-&#39;的时候要先出栈&#xff0c;实际上这里是比较优先级&#xff0c;&#39;*&#39; &#39;/&#39; &#39;^&#39;的优先级更高&#xff0c;所以要先出栈 {if ((AnserReg &#61; Symbol_Pop()) !&#61; Conv_Ok)//运算符出栈到前缀表达式 return AnserReg;Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//出一次加一个空格 }if ((AnserReg &#61; Symbol_Push()) !&#61; Conv_Ok)//压栈 return AnserReg;}else if (Check(&Expression[E_Ptr], isOperatorsLevel2))//待处理字符是&#39;*&#39;或&#39;/&#39; {while (Symbol_Stack.top >&#61; 0 &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel3) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel2) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isBracketRight))//运算符栈非空&#xff0c;且栈顶不是&#39;)&#39; &#39;&#43;&#39; &#39;-&#39; &#39;*&#39; &#39;/&#39;的时候要先出栈&#xff0c;原理同上 {if ((AnserReg &#61; Symbol_Pop()) !&#61; Conv_Ok)//运算符出栈到前缀表达式 return AnserReg;Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//出一次加一个空格 }if ((AnserReg &#61; Symbol_Push()) !&#61; Conv_Ok)//压栈 return AnserReg;}else if (Check(&Expression[E_Ptr], isOperatorsLevel1))//待处理字符是&#39;^&#39;&#xff0c;原理同上 {while (Symbol_Stack.top >&#61; 0 &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel3) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel2) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel1) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isBracketRight))//运算符栈非空&#xff0c;且栈顶不是&#39;)&#39; &#39;&#43;&#39; &#39;-&#39; &#39;*&#39; &#39;/&#39; &#39;^&#39;的时候要先出栈&#xff0c;原理同上 {if ((AnserReg &#61; Symbol_Pop()) !&#61; Conv_Ok)//运算符出栈到前缀表达式 return AnserReg;Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//出一次加一个空格 }if ((AnserReg &#61; Symbol_Push()) !&#61; Conv_Ok)//压栈 return AnserReg;}else if (Check(&Expression[E_Ptr], isOperatorsLevel0))//若待处理的是一元运算符 {if (E_Ptr > 0 && //单目运算符前有值或括弧 Check(&Expression[E_Ptr - 1], isNumberOrDot) ||Check(&Expression[E_Ptr - 1], isBracketRight) ||Check(&Expression[E_Ptr - 1], isConstants))return Conv_MathError;while (Symbol_Stack.top >&#61; 0 &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel3) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel2) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel1) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isOperatorsLevel0) &&!Check(&Symbol_Stack.data[Symbol_Stack.top], isBracketRight))//原理同上 {if ((AnserReg &#61; Symbol_Pop()) !&#61; Conv_Ok)//运算符出栈到前缀表达式 return AnserReg;Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//出一次加一个空格 }if ((AnserReg &#61; Symbol_Push()) !&#61; Conv_Ok)//压栈 return AnserReg;}else//其他的东西就直接都忽略掉吧 {E_Ptr--;}}while (Symbol_Stack.top >&#61; 0)//操作符栈没有变空&#xff0c;说明有操作符没有取出来 {if ((AnserReg &#61; Symbol_Pop()) !&#61; Conv_Ok)//运算符出栈到前缀表达式 return AnserReg;Polish_Notation[&#43;&#43;P_Ptr] &#61; &#39; &#39;;//出一次加一个空格 }Polish_Notation[&#43;&#43;P_Ptr] &#61; Symbol_Stack.data[&#43;&#43;Symbol_Stack.top] &#61; &#39;\0&#39;;//最后结尾加一个截至符 Make_String_Reverse(Polish_Notation, Polishlen);return Conv_Ok;
}Init_type Analytic_Init(Init_type type, char *address)//表达式初始化
{switch (type){case Init_Expression://初始化中缀表达式 Expression &#61; address;break;case Init_Polish_Notation://初始化前缀表达式 Polish_Notation &#61; address;break;default:return Init_Error;}return Init_Ok;
}void ReplaceStringtoChar(char *str, const char *tar, const char chr)//替换表达式中的复杂函数名
{w_size_t position;char *tarposition;w_size_t tarsize;tarsize &#61; (w_size_t)strlen(tar);while ((tarposition &#61; strstr(str, tar)) !&#61; NULL){position &#61; tarposition - str;str[position&#43;&#43;] &#61; chr;while (str[position &#43; tarsize - 1] !&#61; 0){str[position] &#61; str[position &#43; tarsize - 1];position&#43;&#43;;}str[position] &#61; 0;}
}char *Analytic_Simplification(char *str)//复杂函数名化简功能
{a_size_t i;for (i &#61; 0; i }double Store(char *str, w_size_t *p)//转换字符到浮点数
{w_size_t j &#61; *p - 1, i;double n &#61; 0, m &#61; 0;switch (str[*p]){case S_Ans:if (str[*p - 1] &#61;&#61; &#39;-&#39;){*p &#61; *p - 1;return (-1 * Calc_ANS);}elsereturn Calc_ANS;case S_Pai:if (str[*p - 1] &#61;&#61; &#39;-&#39;){*p &#61; *p - 1;return (-1 * _const_Pai_);}elsereturn _const_Pai_;case S_Euler:if (str[*p - 1] &#61;&#61; &#39;-&#39;){*p &#61; *p - 1;return (-1 * _const_Euler_);}elsereturn _const_Euler_;default:break;}while (str[j] >&#61; &#39;0&#39; && str[j] <&#61; &#39;9&#39;)j--;if (str[j] !&#61; &#39;.&#39;)for (i &#61; j &#43; 1; i <&#61; *p; i&#43;&#43;)n &#61; 10 * n &#43; (str[i] - &#39;0&#39;);else{for (i &#61; j &#43; 1; i <&#61; *p; i&#43;&#43;)m &#61; m &#43; pow(0.1, i - j) * (str[i] - &#39;0&#39;);if (str[j] &#61;&#61; &#39;.&#39;){*p &#61; --j;while (str[j] >&#61; &#39;0&#39; && str[j] <&#61; &#39;9&#39;)j--;for (i &#61; j &#43; 1; i <&#61; *p; i&#43;&#43;)n &#61; 10 * n &#43; (str[i] - &#39;0&#39;);}}*p &#61; j;if (str[*p] &#61;&#61; &#39;-&#39;) return(-(n &#43; m));return(n &#43; m);
}Analytic_type Number_Push(w_size_t *i)//数值入栈
{if (Number_Stack.top }double Clear_Infinitesimal(double ans)
{if (ans <1e-10 && ans > -1e-10)return 0;elsereturn ans;
}double Clear_ComplexTan(double num)
{double r1, r2;int i &#61; (int)(num / (_const_Pai_ / 2));r1 &#61; num - i * (_const_Pai_ / 2) &#43; 1e-15;r2 &#61; (i &#43; 1) * (_const_Pai_ / 2) - num &#43; 1e-15;if (i % 2 !&#61; 0 &&((r1 > 0 && r1 <1e-10) ||(r2 > 0 && r2 <1e-10)))return NAN;return num;
}Analytic_type Number_Pop(w_size_t i)//数值出栈
{if (Number_Stack.top >&#61; 0){if (Polish_Notation[i] !&#61; &#39; &#39;)switch (Polish_Notation[i]){case &#39;&#43;&#39;:Number_Stack.data[Number_Stack.top - 1] &#61;Number_Stack.data[Number_Stack.top] &#43; Number_Stack.data[Number_Stack.top - 1];Number_Stack.top--;break;case &#39;-&#39;:Number_Stack.data[Number_Stack.top - 1] &#61;Number_Stack.data[Number_Stack.top] - Number_Stack.data[Number_Stack.top - 1];Number_Stack.top--;break;case &#39;*&#39;:Number_Stack.data[Number_Stack.top - 1] &#61;Number_Stack.data[Number_Stack.top] * Number_Stack.data[Number_Stack.top - 1];Number_Stack.top--;break;case &#39;/&#39;:Number_Stack.data[Number_Stack.top - 1] &#61;Number_Stack.data[Number_Stack.top] / Number_Stack.data[Number_Stack.top - 1];Number_Stack.top--;break;case &#39;^&#39;:Number_Stack.data[Number_Stack.top - 1] &#61;pow(Number_Stack.data[Number_Stack.top], Number_Stack.data[Number_Stack.top - 1]);Number_Stack.top--;break;case S_In:Number_Stack.data[Number_Stack.top] &#61; log(Number_Stack.data[Number_Stack.top]);break;case S_Log:Number_Stack.data[Number_Stack.top] &#61; log10(Number_Stack.data[Number_Stack.top]);break;case S_Exp:Number_Stack.data[Number_Stack.top] &#61; pow(_const_Euler_, Number_Stack.data[Number_Stack.top]);break;case S_Sin:Number_Stack.data[Number_Stack.top] &#61; sin(Number_Stack.data[Number_Stack.top]);Number_Stack.data[Number_Stack.top] &#61; Clear_Infinitesimal(Number_Stack.data[Number_Stack.top]);break;case S_Cos:Number_Stack.data[Number_Stack.top] &#61; cos(Number_Stack.data[Number_Stack.top]);Number_Stack.data[Number_Stack.top] &#61; Clear_Infinitesimal(Number_Stack.data[Number_Stack.top]);break;case S_Tan:Number_Stack.data[Number_Stack.top] &#61; Clear_ComplexTan(Number_Stack.data[Number_Stack.top]);Number_Stack.data[Number_Stack.top] &#61; tan(Number_Stack.data[Number_Stack.top]);Number_Stack.data[Number_Stack.top] &#61; Clear_Infinitesimal(Number_Stack.data[Number_Stack.top]);break;case S_Sqrt:Number_Stack.data[Number_Stack.top] &#61; sqrt(Number_Stack.data[Number_Stack.top]);break;case S_ArcSin:Number_Stack.data[Number_Stack.top] &#61; asin(Number_Stack.data[Number_Stack.top]);break;case S_ArcCos:Number_Stack.data[Number_Stack.top] &#61; acos(Number_Stack.data[Number_Stack.top]);break;case S_ArcTan:Number_Stack.data[Number_Stack.top] &#61; atan(Number_Stack.data[Number_Stack.top]);break;}}elsereturn Conv_MathError;return Conv_Ok;
}Analytic_type Calculation_Results(void)
{Analytic_type res;w_size_t len, i;Init_Stack(Number);len &#61; Get_StringLen(Polish_Notation, Polishlen);for (i &#61; len - 1; i >&#61; 0; i--){if (Check(&Polish_Notation[i], isNumber) || Check(&Polish_Notation[i], isConstants) ||(Check(&Polish_Notation[i], isOperatorsLevel3) && Check(&Polish_Notation[i &#43; 1], isNumber))){if ((res &#61; Number_Push(&i)) !&#61; Conv_Ok)return res;}else{if ((res &#61; Number_Pop(i)) !&#61; Conv_Ok)return res;}}if (Symbol_Stack.top !&#61; 0 || Number_Stack.top !&#61; 0)return Conv_MathError;return Conv_Ok;
}Analytic_type Analytic(Analytic_type type)//表达式解析
{switch (type){case Conv_to_Polish:return Convert_to_Polish();case Calc_Results:return Calculation_Results();default:break;}return Conv_Exception;
}double Get_Answer(void)
{return (Calc_ANS &#61; Number_Stack.data[0]);
}



Analytic.h 头文件&#xff0c;另外还包括几个重要的枚举类型&#xff1a;

//Create Date: 2018-3-4
//Author: Charming
//File: Analytic.h
//Directions: 表达式解析库头文件
//Last edit Date: 2018-3-6#ifndef __ANALYTIC_H_
#define __ANALYTIC_H_#define const_mode const#define USESTRINGLIB 1
#define STRINGLIB_standard 1#ifndef NULL
#define NULL 0
#endif#define Exprlen 100
#define Polishlen 180
#define SymbolMax 80
#define NumberMax 50typedef signed char a_size_t;
typedef signed short w_size_t;typedef enum//初始化枚举类型
{Init_Expression,Init_Polish_Notation,Init_Ok,Init_Error
}Init_type;typedef enum
{Conv_to_Polish,Calc_Results,Conv_Ok,Conv_MathError,Conv_OverFlow, Conv_Exception
}Analytic_type;Init_type Analytic_Init(Init_type type, char *address);
Analytic_type Analytic(Analytic_type type);
char *Analytic_Simplification(char *str);
double Get_Answer();#endif



另外我贴上我测试用的 main.c&#xff0c;也可以作为使用方法的参考&#xff1a;

//Create Date: 2018-3-4
//Author: Charming
//File: Analytic.c
//Version: 1.7.2
//Last edit Date: 2018-3-15
//Directions: 测试源文件#include
#include
#include
#include "Analytic.h"char E_String[Exprlen] &#61; { 0 };
char P_String[Polishlen] &#61; { 0 };int main(void)
{Analytic_type res;Analytic_Init(Init_Expression, E_String);Analytic_Init(Init_Polish_Notation, P_String);while (1){system("cls");printf("C语言利用前缀表达式实现复杂科学计算器\r\n");printf("Test Program Build : %s %s\r\n\r\n", __DATE__, __TIME__);printf("输入一个中缀表达式(退出请输入Exit):");gets_s(E_String, sizeof(E_String));if (strnicmp(E_String, "exit", 4) &#61;&#61; 0)return 0;printf("化简后的中缀表达式: %s\r\n", Analytic_Simplification(E_String));if ((res &#61; Analytic(Conv_to_Polish)) &#61;&#61; Conv_Ok)res &#61; Analytic(Calc_Results);switch (res){case Conv_Ok:printf("前缀表达式: %s\r\n", P_String);printf("\r\n计算结果:%g\r\n\r\n", Get_Answer());break;case Conv_MathError:printf("\r\n数学错误&#xff01;\r\n\r\n");break;case Conv_OverFlow:printf("\r\n堆栈溢出&#xff01;\r\n\r\n");break;case Conv_Exception:printf("\r\n系统异常&#xff01;\r\n\r\n");break;default:break;}system("pause");}return 0;
}



测试截图&#xff1a;




Mathematica验证&#xff1a;




推荐阅读
author-avatar
安茂友恢复_172
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有