研选课堂
HOME
研选课堂
正文内容
plc编程实现pi算式 C++之算式计算器
发布时间 : 2025-02-22
作者 : 小编
访问数量 : 23
扫码分享至微信

C++之算式计算器

#include<iostream>

#include<cmath>

#include<string>

#include<iomanip>

using namespace std;

void menu();//位于calculate函数后面的菜单函数声明

void guide();//位于主函数后面的指导函数的声明

double D_Operate(double x,char op,double y)//双目运算符的运算定义

{

double a;//计算结果

switch(op)

{

case'+': a=x+y;break;

case'-': a=x-y;break;

case'*': a=x*y;break;

case'/': a=x/y;break;

case'^': a=pow(x,y);break;//幂运算包括乘方和开方

}//因为都是利用double进行运算 因此不定义取模运算

return a;

}

double S_Operate(char op,double x)//前缀单目运算符的运算定义

{

double a;//计算结果

switch(op)

{

case's': a=sin(x);break;

case'c': a=cos(x);break;

case't': a=tan(x);break;

case'l': a=log10(x);break;//以10为底的对数

case'n': a=log(x);break;//以e(2.718281828)为底的对数

case'_': a=-x;break;//取负用下划线代替负号 定义为一元运算

}

return a;

}

char Precede(char op1,char op2) //判断符号的优先级 op1在返回的结果符的左边 op2在右边

//用于判定运算符的优先级 以决定是把运算符压栈 还是把栈内的运算符弹出来进行计算

{

if(((op1=='+'||op1=='-')&&(op2=='+'||op2=='-'||op2==')'||op2=='='))||\

((op1=='*'||op1=='/')&&(op2=='+'||op2=='-'||op2=='*'||op2=='/'||op2==')'||op2=='='))\

||(op1=='^'&&(op2=='+'||op2=='-'||op2=='*'||op2=='/'||op2==')'||op2=='='||op2=='s'||op2=='c'||op2=='t'||op2=='_'||op2=='l'||op2=='n'))\

||((op1=='_'||op1=='s'||op1=='c'||op1=='t'||op1=='l'||op1=='n')&&(op2=='+'||op2=='-'||op2=='*'||op2=='/'||op2==')'||op2=='='||op2=='s'||op2=='c'||op2=='t'||op2=='_'||op2=='l'||op2=='n')))

return '>';//上述情况下 栈顶运算符优先级高于待定运算符 需弹栈

if((op1=='('&&op2==')')||(op1=='='&&op2=='='))

return '=';

else

return '<';

}

int illegal_char(string s,int i)//非法输入字符判定函数

{

int j=0;

while(j<i)

{

if(s[j]>='0'&&s[j]<='9')

j++;

else if(s[j]=='+'||s[j]=='-'||s[j]=='*'||s[j]=='/'||s[j]=='.'||s[j]=='('||s[j]==')'||s[j]=='^'||s[j]=='!'||s[j]=='e'||s[j]=='_')

j++;

else if((s[j]=='p'&&s[j+1]=='i')||(s[j]=='l'&&s[j+1]=='n'))

j+=2;

else if((s[j]=='s'&&s[j+1]=='i'&&s[j+2]=='n')||(s[j]=='c'&&s[j+1]=='o'&&s[j+2]=='s')||(s[j]=='t'&&s[j+1]=='a'&&s[j+2]=='n')||(s[j]=='l'&&s[j+1]=='o'&&s[j+2]=='g'))

j+=3;

//以上都是标准的数字字符和运算符 如若存在其他形式的字符 则是非法输入

else

{

cout<<"程序终止,存在非法的字符输入!!!"<<endl;

return 0;

}

}

return 1;//没有非法字符 返回1 否则返回0

}

int match(string s)//栈结构的括号匹配检测函数

{

int i=0,top=0;

char stack[50];

while(s[i]!='\0')

{

if(s[i]=='(')

{

stack[top]=s[i];

top++;

}

//push 左括号压入栈内

if(s[i]==')')

if(stack[top-1]=='(')

{

int a=i+1;

stack[top-1]=NULL;

top--;

}//把与右括号匹配的左括号弹掉

else

{

cout<<"括号输入有误"<<endl;

return 0;//多了右括号 括号失陪 返回非法

}//pop'('

i++;

}

if (top!=0)

{

cout<<"括号输入有误"<<endl;

return 0;//多了左括号 括号失陪 返回非法

}

return 1;//返回合法

}

class NUMstack//运算数栈

{

public:

double num[1000];

int top;

void start()//初始化栈清空栈顶指针置底

{

for(int i=0;i<1000;i++)

num[i]=0;

top=0;

}

void push(char a)//因为有多位数的运算因此不能一压栈就提升栈顶指针

{

num[top]=num[top]*10+(a-'0');//把字符转成数因为每次入栈之前要乘10 所以初始化要清0

}

double pop()

{

top--;

double number=num[top];

num[top]=0;

return number;

}//弹栈函数 弹掉栈顶元素 栈顶归0 top指针下降

double getTop()//取栈顶元素但不必弹栈

{return num[top-1];}

void lift()//提升top指针的函数

{top++;}

};

class OPERstack//运算符栈

{

public:

char oper[1000];

int top;

void start()//初始化函数栈清空栈底放一"="用于判定算式结束

{

oper[0]='=';

for(int i=1;i<1000;i++)

oper[i]=NULL;

top=1;//栈顶指针置于栈底的上一位

}

void push(char a)

{

oper[top]=a;

top++;//与数字栈不同一压栈就可以提升指针

}

char pop()

{

top--;

char op=oper[top];

oper[top]=NULL;

return op;//弹出计算符 用于计算

}

char getTop()

{

return oper[top-1];//取栈顶符号 但不弹栈 可用于判定优先级

}

};

void calculate(string equation)//算式计算函数(关键函数)

{

NUMstack number;//定义运算数栈变量number

OPERstack oper;//定义运算符栈变量oper

number.start();

oper.start();//把两个栈初始化

int i=0,len=0,k;

char p,sig;

double yuan1,yuan2;

while(equation[i]!='\0')

{

len++;

i++;

}//计算等式长度len

if(equation[len-1]!='=')

{

cout<<"输入有误没有输入终止符号--等号"=""<<endl;

return;//检测有没有结束符等号"="

}

int le;

le=illegal_char(equation,len-1);

if(le==0)

return;//有非法字符 不进行后续计算

le=match(equation);

if(le==0)

return;//括号匹配非法 不进行后续计算

for(i=0;i<len;i++)//初步确定合法后开始计算算式

{

if(equation[i]=='!')//阶乘是后缀单目运算符单独进行计算

{

yuan1=number.pop();//弹出栈顶元素做阶乘

if (yuan1==0)

{

number.num[number.top]=0;//0的阶乘为0 压结果入栈

number.lift();

}

else

{

number.num[number.top]=1;

for(k=1;k<=yuan1;k++)//阶乘循环

number.num[number.top]=k*number.num[number.top];

number.lift();//结果入站

}

}

else if(equation[i]>='0'&&equation[i]<='9')

{

number.push(equation[i]);//压数字字符入栈

if((equation[i+1]<'0'||equation[i+1]>'9')&&equation[i+1]!='.')

number.lift();//当整个多位运算数读取完毕后,运算数栈栈顶指针才能提升

}

else if(equation[i]=='p')

{

number.num[number.top]=3.1415926536;//pi值即π 圆周率 要压入数字栈

number.lift();

i++;//pi是两个字符所以要移动扫描算式的指针往后跳一个

}

else if(equation[i]=='e')

{

number.num[number.top]=2.718281828459;//e 自然对数底数 压入运算数栈

number.lift();

}

else if(equation[i]=='.')//小数压栈代码

{

int x=1;

while(equation[i+x]>='0'&&equation[i+x]<='9')

{

number.num[number.top]+=((equation[i+x]-'0')/pow(10,x));//第x位小数入栈

x++;

}

x--;

number.lift();

i=i+x;

}

else if(equation[i]=='(')

{

oper.push(equation[i]);//左括号无条件压栈

}

else//数阶乘左括号判断完毕后其他运算符的分类讨论

{

if(oper.top==1)//运算符栈为空运算符可以无条件入栈

{

if(equation[i]=='l'&&equation[i+1]=='o')

oper.push('l');

else if(equation[i]=='l'&&equation[i+1]=='n')

oper.push('n');//因为log和ln都是小写字母l开头所以要分情况讨论

else

oper.push(equation[i]);

}

else//运算符栈不为空则要进行优先级判断

{

char temp1=oper.getTop();//取出栈顶符号

char temp2;//待入栈符号

if(equation[i]=='l'&&equation[i+1]=='o')

temp2='l';

else if(equation[i]=='l'&&equation[i+1]=='n')

temp2='n';//log与ln的再次讨论

else

temp2=equation[i];

p=Precede(temp1,temp2);

if(p=='<')

oper.push(temp2);//栈顶符优先级较低现在待定的运算符就可以入栈了

if(p=='>'||p=='=')

{

char rep=p;//当栈顶符优先级不低于待入栈的符号 则运算符栈不停地弹栈

//进行运算直到低于待入栈符号为止 rep用于记录比较结果 要多次进行判断

while((rep=='>'||p=='=')&&(oper.top-1>0))

{

sig=oper.pop();

yuan1=number.pop();

yuan2=number.getTop();//靠前的一个运算数只要取得不要弹出来

if(sig=='/'&&yuan1==0)//yuan1是双目运算符后面的第二运算元

{

cout<<"计算时出错!!出现了除数为0的情况!!"<<endl;

return;

}

if(sig=='^'&&yuan2<0&&yuan1>0&&yuan1<1&&(static_cast <int>(1/yuan1))%2==0)

//对负数开偶次根号的限制

{

cout<<"计算时出错!!出现了负数开偶次根号的情况!!"<<endl;

return;

}

if(sig=='_'||sig=='s'||sig=='c'||sig=='t'||sig=='l'||sig=='n')//若为前缀单目运算符

{

double tt;

tt=S_Operate(sig,yuan1);

number.num[number.top]=tt;//运算结果压回原来yuan1在栈内的位置

number.lift();//提升指针

temp1=oper.getTop();

rep=Precede(temp1,temp2);//再判优先级

}

else

{

number.num[(number.top)-1]=D_Operate(yuan2,sig,yuan1);

temp1=oper.getTop();

rep=Precede(temp1,temp2);//双目运算符的计算

}

}

if(equation[i]==')')//如果栈外符是右括号要把与之匹配的左括号弹出栈外

oper.pop();

else if(equation[i]=='l'&&equation[i+1]=='o')

oper.push('l');//代表log的l

else if((equation[i]=='l')&&(equation[i+1]=='n'))

oper.push('n');//代表ln的n

else

oper.push(equation[i]);

}

}

if(equation[i]=='s'||equation[i]=='c'||equation[i]=='t'||(equation[i]=='l'&&equation[i+1]=='o'))

i=i+2;

if(equation[i]=='l'&&equation[i+1]=='n')

i++;

//对于不止一个字符的运算符 sin log ln等等 要移动扫描算式的指针 往后跳一个或两个

}

}

if(number.num[0]==ceil(number.num[0]))

cout<<equation<<number.num[0]<<endl;

else

{cout<<equation<<fixed<<setprecision(8)<<number.num[0]<<endl;}//输出结果控制精度8位小数

//调试时检查运算结束后站内情况的代码段

}

void menu()//菜单函数

{

cout<<"实数型科学算式计算器"<<endl;

cout<<"(徐州工业职业技术学院 混子)"<<endl;

cout<<endl;

cout<<"欢迎使用o(∩_∩)o !!!"<<endl;

cout<<"请选择你需要的功能:(0,1或者2)"<<endl;

cout<<"----------"<<endl;

cout<<"1.使用说明"<<endl;

cout<<"2.计算算式"<<endl;

cout<<"0.退出程序"<<endl;

cout<<"----------"<<endl;

cout<<"你的选择是:";

int choice;

cin>>choice;

switch(choice)

{

case 0:return;

case 1:guide();break;

case 2:

{

system("cls");

char go_on='y';

string equation;

while(go_on=='y')

{

cout<<endl<<endl<<"请输入算式,以=(等号)结束:"<<endl;

cin>>equation;

calculate(equation);

cout<<"继续使用吗?是请输入y 否则输入n:";

cin>>go_on;//可以循环进行算式计算

}

system("cls");

menu();

}

}

}

void main()

{

menu();

}

void guide()//输入规则介绍说明书

{

system("cls");

cout<<"使用说明:"<<endl;

cout<<"输入算式时,请按照下列规则输入:"<<endl;

cout<<"1.四则运算+加 -减 *乘 /除按常规输入,负号用下划线(_)代替,注意将其与减号区别;可用括号()界定优先级"<<endl;

cout<<"2.^幂:幂运算如下乘方输入x^y(x的y次方)如23^6就是23的6次方;开方也这样输入如81^(1/4)[或者81^0.25]表示81开4次方"<<endl;

cout<<"3.!阶乘:6!表示1*2*3*4*5*6;(1+3)!表示4的阶乘,结果是24;1+3!表示1再加上3做阶乘的结果,是7"<<endl;

cout<<"4.pi代表圆周率,即3.1415926536,本计算器利用弧度进行三角函数计算;计算正弦请输入sin,余弦输入cos,正切输入tan;sin(pi/2)就是二分之π弧度对应的正弦值(注意一定要打括号)其他依此类推;"<<endl;

cout<<"5.计算以10为底的对数请输入log,如log1000=3,计算以e(2.718281828)为底的自然对数请输入ln,如lne^4=4,注意指数的输入要规范,如lne^4=4,但是(lne)^4=1,计算算式的对数要在对数符号后面把算式括起来,如ln(3+6*9),计算以其他数为底的对数可利用对数换底公式,如以2为底,16的对数可输入ln16/ln2或者log16/log2结果都是4"<<endl;

cout<<"6.可直接输入e和pi做数值计算"<<endl;

cout<<"7.本计算器的括号只有小括号();不接受中括号[ ]和大括号{ },且算式一定要以等号(=)结束"<<endl;

system("pause");

system("cls");

menu();

}

PLC的简要概述

PLC (Programmable Logic Controller) 早期称为顺序控制器“Sequence Controller”,于 1978 NEMA(National Electrical Manufacture Association) 由美国国家电气协会正式命名为“Programmable LogicController”,其定义为一种电子装置,主要将外部的输入装置如:按键、感应器、开关及脉冲等状态读取后,依据这些输入信号的状态或数值并根据内部储存预先编写的程序,以微处理机执行逻辑、顺序、计时、计数及算式运算,产生相对应的输出信号到输出装置如:继电器 (Relay) 的开关、电磁阀及马达驱动器,以控制机械或程序的操作,来达到机械控制自动化或加工程序之目的。并且藉由其周边的装置(个人计算机/程序书写器)轻易地编辑/修改程序及监控装置状态,进行现场程序的维护与试机调整。而普遍使用于 PLC 程序设计的语言,即是梯形图 (Ladder Diagram) 程序语言。而随着电子科技的发展及产业应用的需要,PLC 的功能也日益强大,例如位置控制及网络功能等,输入信号包含 DI (Digital Input)、AI (Analog Input)、PI (Pulse Input)及 NI (Numerical Input),输出信号也包含了DO (Digital Output)、AO (Analog Output)及 PO (Pulse Output),因此 PLC 在未来的工业控制中,仍将扮演举足轻重的角色。

相关问答

...等于3.5厘米3.r等于四厘米4.r等于1.2厘米【要有算式】_作业帮

[最佳回答]1.d等于5厘米5×3.14=15.7厘米2.d等于3.5厘米3.5×3.14=10.99厘米3.r等于四厘米4×2×3.14=25.12厘米4.r等于1.2厘米1.2×2×3...

圆周率算式怎么列?

圆周率算式的列法如下:1.首先,可以使用π表示圆周率,它是一个无理数,约等于3.14159;2.其次,圆周率的计算可以通过测量圆的周长和直径的比值来获得,这个...3...

圆周率计算方法简便?

3、圆周率表示是一个常数,约等于3.141592654,代表圆周长和直径的比值。圆周率是一个无理数,即无限不循环小数。圆周率(Pi)是圆的周长与直径的比值,一般用...

..今天之内上交加5分...今天下午8为止...要有算式_作业帮

[最佳回答]162-40.5pi面积为去掉两个半径为4.5的圆,故剩下面积为:18×9-2×π×4.5×4.5即162-40.5π

...长满了青草.栓牛的绳长4米,求牛所能吃到的草.(要算式)_作业帮

[最佳回答]3.14X4X4X2/3+3.14X1X1X2/3X2=37.68

围成的正方形面积是多少?要有算式!】作业帮

[最佳回答]半径3,则周长为2*pi*3=6*pi剪刀剪去剩下2/3为4*pi正方形各边相同,边长为pi正方形面积为pi^2

小棒的直径是多少?用方程,不用算式!_作业帮

[最佳回答]设周长是x100x+75.36=150x+18.84x=1.1304周长=2PI*R1.1304=2*3.1415926*rr=0.18所以直径d=0.36cm

时速大约多少千米保留整数写算式快30分钟内答完_作业帮

[最佳回答]圆周长=πx1.02≈3.14x1.02=3.2028米每分钟所行路程=355x3.2028=1136.994米时速=1136.994x60=68219.64米≈68千米圆周长=πx1.02≈3.1...

...少分钟才能全部输送完?(得数保留一位小数)要算式过程】作业帮

[最佳回答]混泥土在管道内流速是每分钟35m相当于每分钟输送3.14*0.05*0.05*35=0.275立方一车7立方,输送时间=7/0.275=25.5分钟.如有帮助,望采纳.混泥土在管道...

dx(t)/dt=57500-2.75*10^-7*exp(x(t)/11)-76333*(sin(2*pi...

[最佳回答]dy/dx=a1-a2*exp(cy)-a3*(sin(x))^2,a1~a3,c都是已知常数.先求1个特解,dt/dx=a1-a3*(sinx)^2=a1-a3[1-...

 学车考试  方正科技电脑 
王经理: 180-0000-0000(微信同号)
10086@qq.com
北京海淀区西三旗街道国际大厦08A座
©2025  上海羊羽卓进出口贸易有限公司  版权所有.All Rights Reserved.  |  程序由Z-BlogPHP强力驱动
网站首页
电话咨询
微信号

QQ

在线咨询真诚为您提供专业解答服务

热线

188-0000-0000
专属服务热线

微信

二维码扫一扫微信交流
顶部