(完整版)数学表达式计算(c语言实现)
C语言从入门到精通(吐血分享)

六大表达式一、算术表达式(数学表达式)(1)运算符:数学:{} [] () + - * / + -C:()、+/-、* / %、+/-正负(2)单目、双目运算符单目:一个操作数 +5 -9双目:两个操作数 5+6 7*8(3)%:<1>双目运算符<2>操作数:两个数都是整型资料1%2<3>奇数: x%2!=0偶数: x%2==0整除: %(4)在算术运算中,如果运算符两端的类型都是整型数据,那么结果是整型资料1/2 0 5/3 1 8/9 0 9/8 1在算术运算中,如果运算符两端的类型不一致,向空间大的一方转化. 1/2.0 1.0/2.0 0.5 1.0/5 1.0/5.0 0.22 4(5)优先级:(6)结合性:(7)使用多层括号,一律使用小括号(8)强制性类型转化格式:(类型名)表达式注:1)类型名括号不能省2)不存在四舍五入2.赋值表达式(1)格式变量名=表达式(2)变数的实质:存储单元(3) =:赋值号==:等号优先级:只比逗号高结合性:自右向左(4)表达式:常量、变数、六大表达式(5)在赋值表达式中,赋值号的左端只能为变量名5+8=a b=a(6) int x=2,y=3;x=y:将变量y所代表的单元中的值取出来赋值给变量x所代表的单元中x=x+1:将变量x所代表的单元中的值取出来+1赋值给变量x代表的单元中x=x:左x: 代表x所标识的单元右x:将变量x所代表的单元中的值取出来单元=值(7)变量中的值在不断进行更新x=2x=3x=99(8)复合赋值表达式(算术和赋值) 1)运算符:*= /= %= += -=2)优先级:与”=“同级3)结合性:自右向左4)复合赋值有隐含小括号功能3.关系表达式(1)逻辑值平时 C 5678 -2真非0 1假 0 0(2)运算符> >= < <= == != (3)优先级> >= < <= == != (4)结合性自左向右(5)结果:逻辑值5<6 7>94.逻辑表达式(1)运算符!:(非补集)&&:(与交集)||:(或者并集)(2)!:单目运算&& ||:双目(3)优先级高到低:! && ||(4)结合性!:自右向左&& ||:自左向右(5)使用!0 1 !非0 0非0&&非0 1 1||1 1非0&&0 0 1||0 10&&非0 0 0||1 10&&0 0 0||0 0(6)结果:逻辑值(1,0)(7)数学表示方式|x|<=9 -9<=x<=9 x>=-9&&x<=9|x|>=9 x>=9或x<=-9 x>=9||x<=-9(8)断路问题<1> 在逻辑&&运算中,如果表达式1已经为逻辑假,表达式2不用执行,该表达式值为逻辑假<2>在逻辑||运算中,如果表达式1已经为逻辑真,表达式2不用执行,该表达式值为逻辑真5.条件表达式格式:表达式1?表达式2:表达式3(1)三目运算(2)运算过程:表达式1为真,执行表达式2表达式1为假,执行表达式36.逗号表达式(1)格式:表达式1,表达式2,表达式3,表达式4,……,表达式n (2)优先级:所有运算符中优先级最低(3)结合性:自左向右int a=8;a+=3,a=5,a+3; ?a 表达式的值?附:<1>++ 、--1>功能++:+1 自动赋值--: -1 自动赋值2>单目运算3>操作数可以放在运算符的右边也可以放在运算符的左边 i++ ++i i-- --i4>操作数可以为整型、实型的变量 2++ 2=2+1 错i++ i=i+1 ++i i=i+1i-- i=i-1 --i i=i-15>表达式值和变数值int i;表达式值变数值i=5 i++ 5 6i=5 ++i 6 6i=5 i-- 5 4i=5 --i 4 4只要给出式子的整体(i++,--i)则使用的是表达式的值;如果给出变量名,使用的是变量值int i=5;j=40/i++; j=40/6 66>-i++:-(i++) j=-i++; j=-5 i=6<2>所有运算符的优先级(六个表达式)高=》低() ++/-- !算术表达式关系表达式逻辑表达式条件表达式赋值表达式逗号表达式。
数学公式的c语言表达式

数学公式的c语言表达式数学公式是我们日常生活和工作中不可或缺的一部分。
在计算机编程中,我们也需要使用数学公式来解决一些问题。
而这些数学公式需要通过c语言表达式来实现。
本文将介绍一些常见的数学公式及其c语言表达式,供大家参考。
一、基本运算符在c语言中,常见的数学运算符包括加号(+)、减号(-)、乘号(*)、除号(/)和求模运算符(%),它们的优先级从高到低依次为:乘、除、求模、加、减。
二、三角函数1.正弦函数在c语言中,正弦函数可以使用math库中的sin()函数实现。
例如计算30度的正弦值,可以用以下代码:#include <stdio.h>#include <math.h>int main(){double angle = 30;double radian = angle * M_PI / 180;double sin_value = sin(radian);printf('sin(30) = %f', sin_value);return 0;}2.余弦函数在c语言中,余弦函数可以使用math库中的cos()函数实现。
例如计算45度的余弦值,可以用以下代码:#include <stdio.h>#include <math.h>int main(){double angle = 45;double radian = angle * M_PI / 180;double cos_value = cos(radian);printf('cos(45) = %f', cos_value);return 0;}3.正切函数在c语言中,正切函数可以使用math库中的tan()函数实现。
例如计算60度的正切值,可以用以下代码:#include <stdio.h>#include <math.h>int main(){double angle = 60;double radian = angle * M_PI / 180;double tan_value = tan(radian);printf('tan(60) = %f', tan_value);return 0;}三、指数和对数函数1.指数函数在c语言中,指数函数可以使用math库中的exp()函数实现。
c语言算术表达式求值

c语言算术表达式求值【实用版】目录1.引言2.C 语言算术表达式的基本概念3.C 语言算术表达式的求值方法4.实际应用示例5.总结正文【引言】在 C 语言编程中,算术表达式是用来进行数值计算的重要工具。
本篇文章将为大家介绍 C 语言算术表达式的求值方法。
【C 语言算术表达式的基本概念】C 语言中的算术表达式主要包括以下几种:1.一元运算符:例如+、-、*、/等,用于对一个数值进行操作。
2.二元运算符:例如+、-、*、/等,用于对两个数值进行操作。
3.关系运算符:例如<、>、<=、>=、==、!=等,用于比较两个数值的大小或相等性。
4.逻辑运算符:例如&&、||、! 等,用于进行逻辑判断。
【C 语言算术表达式的求值方法】C 语言中,算术表达式的求值主要遵循以下规则:1.先进行括号内的运算,再进行括号外的运算。
2.先进行乘除法运算,再进行加减法运算。
3.关系运算符和逻辑运算符的优先级较低,从左到右依次进行运算。
【实际应用示例】下面我们通过一个实际的 C 语言程序,来演示算术表达式的求值过程。
```c#include <stdio.h>int main() {int a = 10, b = 5;int result;result = a + b * (a - b) / (a * b);printf("The result is: %d", result);return 0;}```在这个程序中,我们定义了两个整数变量 a 和 b,并通过算术表达式计算 result 的值。
根据我们之前提到的算术表达式求值规则,我们可以将这个表达式分解为以下几个步骤:1.计算括号内的值:a - b = 10 - 5 = 52.计算乘法运算:b * (a - b) = 5 * 5 = 253.计算除法运算:(a * b) / (a * b) = 14.计算加法运算:a + 25 = 10 + 25 = 355.输出结果:printf("The result is: %d", result); 输出 35【总结】通过本篇文章的介绍,相信大家已经对 C 语言算术表达式的求值方法有了更加深入的了解。
C语言基础简单的数学运算的代码

C语言基础简单的数学运算的代码#include <stdio.h>int main() {// 定义并初始化变量int num1 = 10;int num2 = 5;// 加法运算int sum = num1 + num2;printf("加法运算结果:%d\n", sum);// 减法运算int difference = num1 - num2;printf("减法运算结果:%d\n", difference);// 乘法运算int product = num1 * num2;printf("乘法运算结果:%d\n", product);// 除法运算float quotient = (float)num1 / num2;printf("除法运算结果:%.2f\n", quotient);// 求余运算int remainder = num1 % num2;printf("求余运算结果:%d\n", remainder);return 0;}以上是一个简单的C语言程序,实现了基本的数学运算功能。
程序运行后,会输出每个数学运算的结果。
接下来我会逐行解释代码的含义和执行过程。
首先,在程序的开头我们使用了#include <stdio.h>这行代码,这是为了包含C语言标准库中的输入输出函数,以便后续可以使用printf()函数打印结果。
接着,在main()函数中,我们定义并初始化了两个整型变量num1和num2,分别赋值为10和5。
这两个变量代表了我们要进行数学运算的两个操作数。
然后,我们使用加法运算将num1和num2相加得到sum,并使用printf()函数打印出加法运算的结果。
接着,我们使用减法运算将num1减去num2得到difference,并使用printf()函数打印出减法运算的结果。
C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这⼀篇就够了⼀、种类介绍算术表达式有三种:前缀表达式、中缀表达式和后缀表达式。
⼀般⽤的是中缀,⽐如1+1,前后缀就是把操作符移到前⾯和后⾯,下⾯简单介绍⼀下这三种表达式。
1、前缀表⽰法前缀表⽰法⼜叫波兰表⽰法,他的操作符置于操作数的前⾯(例:+ 1 2),是波兰数学家扬·武卡谢维奇1920年代引⼊的,⽤于简化命题逻辑。
因为我们⼀般认为操作符是在操作数中间的,所以在⽇常⽣活中⽤的不多,但在计算机科学领域占有⼀席之地。
⼀般的表⽰法对计算机来说处理很⿇烦,每个符号都要考虑优先级,还有括号这种会打乱优先级的存在,将使计算机花费⼤量的资源进⾏解析。
⽽前缀表⽰法没有优先级的概念,他是按顺序处理的。
举个例⼦:9-2*3这个式⼦,计算机需要先分析优先级,先乘后减,找到2*3,再进⾏减操作;化成前缀表⽰法就是:- 9 * 2 3,计算机可以依次读取,操作符作⽤于后⼀个操作数,遇到减就是让9减去后⾯的数,⽽跟着9的是乘,也就是说让9减去乘的结果,这对计算机来说很简单,按顺序来就⾏了。
2、中缀表⽰法这也就是我们⼀般的表⽰法,他的操作符置于操作数的中间(例:1 + 2),前⾯也说过这种⽅法不容易被计算机解析,但他符合⼈们的普遍⽤法,许多编程语⾔也就⽤这种⽅法了。
在中缀表⽰法中括号是必须有的,要不然运算顺序会乱掉。
3、后缀表⽰法后缀表⽰法⼜叫逆波兰表⽰法,他的操作符置于操作数的后⾯(例:1 2 +),他和前缀表⽰法都对计算机⽐较友好,但他很容易⽤堆栈解析,所以在计算机中⽤的很多。
他的解释过程⼀般是:操作数⼊栈;遇到操作符时,操作数出栈,求值,将结果⼊栈;当⼀遍后,栈顶就是表达式的值。
因此逆波兰表达式的求值使⽤堆栈结构很容易实现,且能很快求值。
注意:逆波兰记法并不是简单的波兰表达式的反转。
因为对于不满⾜交换律的操作符,它的操作数写法仍然是常规顺序,如,波兰记法/ 6 3的逆波兰记法是6 3 /⽽不是3 6 /;数字的数位写法也是常规顺序。
c语言五则运算代码

c语言五则运算代码C语言是一种广泛应用于计算机编程的编程语言,它具有灵活、高效的特点,常被用于进行各种数学计算和表达式求值。
本文将围绕C语言的五则运算(加法、减法、乘法、除法、取余)展开,探讨其在实际编程中的应用。
一、加法运算加法运算是最基本的数学运算之一,在C语言中使用加号(+)来表示。
在实际编程中,加法运算常用于计算两个数的和。
例如,我们可以编写一个程序,实现输入两个数并计算它们的和:```c#include <stdio.h>int main() {int a, b, sum;printf("请输入两个整数:\n");scanf("%d %d", &a, &b);sum = a + b;printf("它们的和为:%d\n", sum);return 0;}```二、减法运算减法运算是计算两个数之差的操作,在C语言中使用减号(-)来表示。
我们可以编写一个程序,实现输入两个数并计算它们的差:```c#include <stdio.h>int main() {int a, b, difference;printf("请输入两个整数:\n");scanf("%d %d", &a, &b);difference = a - b;printf("它们的差为:%d\n", difference);return 0;}```三、乘法运算乘法运算是计算两个数的积的操作,在C语言中使用星号(*)来表示。
我们可以编写一个程序,实现输入两个数并计算它们的积:```c#include <stdio.h>int main() {int a, b, product;printf("请输入两个整数:\n");scanf("%d %d", &a, &b);product = a * b;printf("它们的积为:%d\n", product);return 0;}```四、除法运算除法运算是计算两个数的商的操作,在C语言中使用斜杠(/)来表示。
C语言下表达式的自动计算(两种方式)(报告+源代码)

一、设计思想第一种算法:将中缀表达式转为后缀表达式,然后通过后缀表达式计算出算术表达式的结果。
核心思想:第一步:中缀变后缀。
首先,我们做出一个统一的Node结构体,结构体内部包含四个属性,分别是操作符的字符‘op’,char类型;操作符的优先级‘level’,int 类型;数字的浮点数数值‘od’,float类型;Node的标识符,int类型。
然后,定义一个Node结构体类型的数组*listNode,这里的*listNode用的是全局变量,为了方便在得到后缀表达式后,不需再传递给计算的方法。
定义一个存放操作符的栈,遍历用户输入的算术表达式(不考虑错误情况),在遍历的过程中如果遇到数字,直接将数字存放在*listNode里面;如果遇到了操作符,则判断操作符栈目前是不是为空,如果为空,直接将遇到的操作符放入操作符栈中,如果操作符栈不为空,那么观察操作符栈中栈顶的操作符,然后再次判断当前遇到的操作符的优先级是不是比栈顶的操作符的优先级高,如果是,那么将当前的操作符入操作符栈;如果不是,那么将操作符栈的栈顶操作符取出,追加到*listNode中,然后继续观察栈顶操作符,直到当前的操作符的优先级比栈顶操作符的优先级高或者操作符栈为空时,将当前操作符入操作符栈。
如果遇到了左括号,那么定义其优先级为最低,然后直接将左括号入操作符栈。
如果遇到了右括号,那么开始从操作符栈中取出操作符追加到*listNode中,直到遇到了与之对应的左括号,然后将左括号和右括号一起销毁。
当遍历完成了算术表达式之后,这时判断操作符栈是否为空,如果不为空,那么从操作符栈中依次取出栈顶操作符追加到*listNode中,直到操作符栈为空,那么就代表我们将中缀表达式转变成为了后缀表达式。
第二步:通过得到的后缀表达式,计算算术表达式。
首先,定义一个数字栈用来存放数值。
然后,遍历*listNode中的每一个Node,如果Node是一个数字,那么就将数字入数字栈,如果Node是一个操作符,那么就从数字栈中依次取出栈顶的两个数字,然后根据操作符计算这两个数字,将得到的结果再次入数字栈,直到遍历*listNode完成,最终数字栈中会只剩下一个Node,那就是我们计算出算术表达式的结果,将结果返回给main 函数用来输出。
算术表达式计算的实现(C语言)

1 )表达式 中缀转化为后缀; 2 )后缀表达式的计算 。 ( 1 ) 中缀 转 化 为后 缀 在本 程序 中,建立 了一个操作符栈o p 和一个字符数组e x p 。o p 栈存放表达式中的 操作符 ( 运算符号 ),e x p 数组中存放转换 以后 的后 缀 表 达 式 。具 体 运 行 过 程 如 下 : 首先 ,输 入一个算术表达式 ( 中缀 ),将 其存入事 先定义的s t r 数 组 中 。对 s t r 数 组 中的每个 字符依次扫描 ,如果 是数字或者 是小数点,则直接存入e x p 数组中,每存入 个数字或小数点,在后面加一个# 作为分 隔符 。 如果是操作 符,并且栈为 空则 直接入 栈 ;如果栈不为空格 ,则与栈顶的操作符 进 行优先级 比较 ,若 比栈 顶的优先级高 , 则入 栈;反之 ,则 出栈将 其操作符存放到 e x p 数组 中,知道栈顶 元素 的优先级等级低 于扫 描的操作符 ,则此操 作符入栈 ;如果 是左括号,则直接入栈 ;如果是右括号 , 则出栈存入 ̄ 1 ] e x p 数组,直 到遇到左括号。 直扫描 ̄ J l s t r 的结束符号\ O 。结束后看0 p 栈是否为 空,若不为空则继续出栈存入e x p 数组中,直到栈为空。到此在e x p 数组最后 在加 结束符号\ 0 。 ( 2 ) 后缀表达 式的计算 在本程序 运行过程 中,先建立一个 数 值栈0 d ,用来存放 数值 。首先,对e x p 数组
I 一 学 熏 …………………………一 算 术 表 达 式 计 算 的实 现 ( c语 言 )
西安 电子科技 大学 钱学林
【 摘要 】算术表达 武实现程序是计 算数学表达武方法的一种。本程序 由( : 语言编写 ,主要涉及一 维结构体 、宏定义、函数、 中缀、后缀 等基本 知识。本程序 由七个 函数模 块来实现功能 ,分别为 负号处理、 中缀转后缀、优先级 比较、乘方的计算、算术运算、后缀表达 式计算六个子 函数和 一个 主函数 ,分别使 用到了结构、s w i t h q .  ̄ 、数组、 后缀 中缀表示等知识。 【 关键 词】后缀 ;中缀 ;函数;结构体
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、设计思想计算算术表达式可以用两种方法实现:1.中缀转后缀算法此算法分两步实现:先将算术表达式转换为后缀表达式,然后对后缀表达式进行计算。
具体实现方法如下:(1)中缀转后缀需要建一个操作符栈op和一个字符数组exp,op栈存放操作符,字符数组用来存放转换以后的后缀表达式。
首先,得到用户输入的中缀表达式,将其存入str数组中。
对str数组逐个扫描,如果是数字或小数点,则直接存入exp数组中,当扫描完数值后,在后面加一个#作为分隔符。
如果是操作符,并且栈为空直接入栈,如果栈不为空,与栈顶操作符比较优先等级,若比栈顶优先级高,入栈;如果比栈顶优先级低或相等,出栈将其操作符存到exp数组中,直到栈顶元素优先等级低于扫描的操作符,则此操作符入栈;如果是左括号,直接入栈,如果是右括号,出栈存入exp数组,直到遇到左括号,左括号丢掉。
然后继续扫描下一个字符,直到遇到str中的结束符号\0,扫描结束。
结束后看op栈是否为空,若不为空,继续出栈存入exp数组中,直到栈为空。
到此在exp数组最后加结束字符\0。
我们就得到了后缀表达式。
(2)后缀表达式计算此时需要一个数值栈od来存放数值。
对exp数组进行逐个扫描,当遇到数字或小数点时,截取数值子串将其转换成double类型的小数,存入od栈中。
当遇到操作符,从栈中取出两个数,进行计算后再放入栈中。
继续扫描,知道扫描结束,此时值栈中的数值就是计算的结果,取出返回计算结果。
2.两个栈实现算法此算法需要两个栈,一个值栈od,一个操作符栈op。
将用户输入的数学表达式存入str数组中,对其数组进行逐个扫描。
当遇到数字或小数点,截取数值子串,将其转换成double类型的数值存入od栈中;当遇到左括号,直接入op栈;遇到右括号,op栈出栈,再从值栈od中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到操作符栈栈顶为左括号,将左括号丢掉。
如果遇到操作符,若op栈为空,直接入栈;若栈不为空,与栈顶元素比较优先等级,若比栈顶操作符优先等级高,直接入op栈,如果低于或等于栈顶优先等级,op栈出栈,再从值栈中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到栈顶优先等级低于扫描的操作符等级,将此操作符入op栈。
继续扫描直到遇到str中的结束字符\0,扫描结束。
此时看操作符栈是否为空,若不为空,出栈,再从值栈中取出两个数值进行计算,将其结果存入值栈,一直进行此操作,直到操作符栈为空。
此时把值栈中的数值取出,即为所得的最终计算结果。
二、算法流程图第一种算法:中缀转后缀算法其主函数流程图为:返回计算结果图1 主函数算法流程图中缀转后缀算法流程图如下:放入exp数组中图2 中缀转后缀算法流程图计算后缀表达式流程图如下:图3 后缀表达式计算流程图第二种算法:两个栈算法其主函数流程图为:返回计算结果图4 主函数算法流程图直接计算数学表达式流程图如下:图5 直接计算表达式流程图三、源代码下面给出的是用中缀转后缀算法实现的程序的源代码:#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define MAXSIZE 100 //定义宏,数组最大长度为100//函数实现中缀转后缀,将存储数学表达式的数组str传参进来,exp存储后缀表达式void trans(char str[],char exp[]){struct{char data[MAXSIZE];//用来存放操作符int top;//数组下标}op;//用结构体创建操作符栈char ch;int i=0,j=0,tempi=0;op.top=-1;//给操作符栈初始化,令下标为-1while(ch!='\0'){ch=str[i]; //取str数组的第i个元素赋值给chif((ch>='0'&& ch<='9') || ch=='.')//对数值操作{tempi=i;//若ch为数字或小数点,将其下标值赋给临时下标tempi//依次向后扫描str数组,若一直为数字,跳入while循环while((ch>='0' && ch<= '9') || ch == '.'){tempi++;exp[j]=ch;//将数字存入exp数组中j++;ch=str[tempi];//取str数组中下标为tempi的元素赋给ch}exp[j]='#';j++;//用#做分隔符,将数值分隔开i=tempi;//跳出循环,将此时的tempi赋给i,继续向后扫描}//对操作符操作else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='%' || ch == '(' || ch == ')'){int level(char op);//声明level函数if(ch=='(')//如果为(,直接进栈{op.top++;op.data[op.top]=ch;//进栈操作}else if(ch==')'){//如果为),一直出栈直到遇到(while(level(op.data[op.top])!=-1)//若栈顶元素不为(,进入while循环{exp[j]=op.data[op.top];//操作符出栈,存入exp数组中op.top--;j++;if(op.top==-1)break;//如果栈为空,跳出循环}op.top--;//左括号pop出来}else if(op.top==-1)//如果栈为空,直接进栈{op.top++;op.data[op.top]=ch;//进栈操作}//如果所扫描的操作符优先等级比栈顶元素高,直接进栈else if(level(ch)>level(op.data[op.top])){op.top++;op.data[op.top]=ch;//进栈操作}else{//如果所扫描的操作符优先等级没有栈顶元素高,//一直出栈直到比栈顶元素优先级高while(level(ch)<=level(op.data[op.top])){exp[j]=op.data[op.top];//出栈存入exp数组中op.top--;j++;if(op.top==-1)break;//如果栈为空,跳出循环}op.top++;op.data[op.top]=ch;//比栈顶元素优先级高,入栈}i++;//str下标加1,向后扫描}}while(op.top!=-1)//扫描结束后如果操作符栈不为空,出栈直至为空{exp[j]=op.data[op.top];//出栈存入exp数组中op.top--;j++;}exp[j]='\0';//赋\0结束exp字符数组}int level(char op)//判断操作符优先等级{if(op == '+' || op == '-')//若为+、-,等级为1return 1;else if(op == '*' || op == '/' || op == '%')return 2; //若为*、/、%,等级为2else if(op == '(')return -1 ; //若为(,等级为-1elsereturn -3; //其他等级为-3;}double calvalue(double od1,double od2,char tempop)//计算{switch(tempop){case '+':return od1 + od2; //计算加法case '-':return od1 - od2;//计算减法case '*':return od1 * od2;//计算乘法case '/':return od1 / od2;//计算除法case '%':return fmod(od1,od2);//求余}return 0;}double calculate(char exp[])//计算后缀表达式{struct //用结构体创建值栈{double data[MAXSIZE]; //存储数值int top;}od;double d; //声明d变量存储数值double od1,od2; //存储值栈依次pop出来的操作数char ch;char tempch[20]; //声明临时数组存储子串int j=0,t;int length=strlen(exp);//计算exp数组的长度od.top=-1; //初始化值栈,令下标为-1while(j<length){ch=exp[j];//提取exp中第j个元素if(ch!='+' && ch!='-' && ch!= '*' && ch!='/' && ch!='%'){//如果为数字或小数点t=0;while((ch>='0' && ch<='9') ||ch=='.'){tempch[t]=ch;t++;//依次存放到临时数组中j++;ch=exp[j];}tempch[t]='\0';//结束tempch数组d=atof(tempch);//将子串转化成double类型的数od.top++;od.data[od.top]=d;//入值栈}else //若为操作符,从值栈中pop出两个数计算{od2=od.data[od.top];od.top--;//先出栈的赋给od2od1=od.data[od.top]; //后出栈的赋给od1od.data[od.top]=calvalue(od1,od2,ch); //计算出结果后再入栈}j++;}return od.data[od.top];//将结束后值栈中的数pop出来,即为计算结果}main(){char str[MAXSIZE],exps[MAXSIZE]; //定义两个数组printf("请输入算术表达式:\n");gets(str); //从控制台输入算数表达式printf("表达式为:%s\n",str);trans(str,exps); //调用trans函数,得到后缀表达式printf("后缀表达式:%s\n",exps);printf("结果为:%lf\n", calculate(exps)); //调用calculate函数,计算结果}下面给出的是用两个栈算法实现的程序的源代码:#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define MAXSIZE 100 //定义宏,数组最大长度为100double calculate(char str[]){struct //用结构体创建操作符栈{char data[MAXSIZE];//用来存放操作符}op;struct //用结构体创建值栈{double data[MAXSIZE];//用来存放操作数int top;}od;char ch;char tempch[20];//声明临时数组存储子串int j=0,t;double d;double od1,od2;//存储值栈依次pop出来的操作数char tempop;int length=strlen(str);//计算str数组的长度op.top=-1;//初始化操作符栈,令下标为-1od.top=-1;//初始化值栈while(j<length){ch=str[j];if((ch>='0' && ch<='9') ||ch=='.')//若为数值或小数点{d=0;t=0;while((ch>='0' && ch<='9') ||ch=='.')//截取子串{tempch[t]=ch;t++;//赋值给临时数组j++;ch=str[j];}tempch[t]='\0';d=atof(tempch);//将子串转化成double类型的数od.top++;od.data[od.top]=d;//入值栈}//对操作符操作else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='%' || ch == '(' || ch == ')') {if(ch=='(')//如果为(,直接进栈{op.top++;op.data[op.top]=ch;//进栈操作}else if(ch==')')//如果为),一直出栈直到遇到({int level(char op);//声明level函数while(level(op.data[op.top])!=-1)//若栈顶元素不为(,进入while循环{//声明calvalue函数double calvalue(double od1,double od2,char tempop);od2=od.data[od.top];od.top--;od1=od.data[od.top];tempop=op.data[op.top];op.top--;od.data[od.top]=calvalue(od1,od2,tempop);//计算出结果后入值栈if(op.top==-1)break;//如果操作符栈为空,跳出循环}op.top--;//左括号pop出来}else if(op.top==-1)//如果栈为空,直接进栈{op.top++;op.data[op.top]=ch;//进栈操作}//如果所扫描的操作符优先等级比栈顶元素高,直接进栈else if(level(ch)>level(op.data[op.top])){op.top++;op.data[op.top]=ch;//进栈操作}else{//如果所扫描的操作符优先等级没有栈顶元素高,//一直出栈直到比栈顶元素优先级高while(level(ch)<=level(op.data[op.top])){od2=od.data[od.top];od.top--;od1=od.data[od.top];tempop=op.data[op.top];op.top--;od.data[od.top]=calvalue(od1,od2,tempop);//计算结果后入值栈if(op.top==-1)break;//如果栈为空,跳出循环}op.top++;op.data[op.top]=ch;//比栈顶元素优先级高,入操作符栈}j++;//str下标加1,向后扫描}}while(op.top!=-1)//扫描结束后如果操作符栈不为空,出栈直至为空{od2=od.data[od.top];od.top--;od1=od.data[od.top];tempop=op.data[op.top];op.top--;od.data[od.top]=calvalue(od1,od2,tempop);//计算结果后入值栈}return od.data[od.top];//将结束后值栈中的数pop出来,即为计算结果}int level(char op)//判断操作符优先等级{if(op == '+' || op == '-')//若为+、-,等级为1return 1;else if(op == '*' || op == '/' || op == '%')return 2; //若为*、/、%,等级为2else if(op == '(')return -1 ; //若为(,等级为-1elsereturn -3; //其他等级为-3;}double calvalue(double od1,double od2,char tempop)//计算{switch(tempop){case '+':return od1 + od2;//计算加法case '-':return od1 - od2;//计算减法case '*':return od1 * od2;//计算乘法case '/':return od1 / od2;//计算除法case '%':return fmod(od1,od2);//求余}return 0;}void main(){char str[MAXSIZE];//定义str数组存放数学表达式printf("输入算术表达式:\n");gets(str); //从控制台输入算数表达式printf("结果是:%lf\n",calculate(str));//调用calculate函数,计算结果}四、运行结果图6 中缀转后缀算法运行结果图7 两个栈算法运行结果五、遇到的问题及解决编程的前期工作很重要,需要明确的理清思路,而编写运行的过程中更是会出现很多问题,有因粗心造成的拼写错误,有语法错误,也有逻辑错误。