如何用c语言做简易计算器(C语言也能写一个高级-函数型计算器)

.函数计算器是电子计算器的一种,可进行乘方、开方、指数、对数、三角函数、统计等方面的运算,又称科学型计算器仅供参考:,下面我们就来聊聊关于如何用c语言做简易计算器?接下来我们就一起去了解一下吧!

如何用c语言做简易计算器(C语言也能写一个高级-函数型计算器)

如何用c语言做简易计算器

.

函数计算器是电子计算器的一种,可进行乘方、开方、指数、对数、三角函数、统计等方面的运算,又称科学型计算器。仅供参考:

/*---------------------------------------

函数型计算器(VC 6.0,Win32 Console)

功能:

目前提供了10多个常用数学函数:

⑴正弦sin

⑵余弦cos

⑶正切tan

⑷开平方sqrt

⑸反正弦arcsin

⑹反余弦arccos

⑺反正切arctan

⑻常用对数lg

⑼自然对数ln

⑽e指数exp

⑾乘幂函数^

⑿向上取整ceil

⒀向下取整floor

⒁四舍五入取整round

用法:

如果要求2的32次幂,可以打入2^32<回车>

如果要求30度角的正切可键入tan(Pi/6)<回车>

注意不能打入:tan(30)<Enter>

如果要求1.23弧度的正弦,有几种方法都有效:

sin(1.23)<Enter>

sin 1.23 <Enter>

sin1.23 <Enter>

如果验证正余弦的平方和公式,可打入sin(1.23)^2 cos(1.23)^2 <Enter>或sin1.23^2 cos1.23^2 <Enter>

此外两函数表达式连在一起,自动理解为相乘如:sin1.23cos0.77 cos1.23sin0.77就等价于sin(1.23)*cos(0.77) cos(1.23)*sin(0.77)

当然你还可以依据三角变换,再用sin(1.23 0.77)也即sin2验证一下。

本计算器充分考虑了运算符的优先级因此诸如:2 3*4^2 实际上相当于:2 (3*(4*4))

另外函数名前面如果是数字,那么自动认为二者相乘.

同理,如果某数的右侧是左括号,则自动认为该数与括弧项之间隐含一乘号。

如:3sin1.2^2 5cos2.1^2 相当于3*sin2(1.2) 5*cos2(2.1)

又如:4(3-2(sqrt5-1) ln2) lg5 相当于4*(3-2*(√5 -1) loge(2)) log10(5)

此外,本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。

----------------------------------------*/

#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <cstring>

#include <cctype>

#include <cmath>

#include <stdio.h>

#include <string.h>

#include <windows.h>

usingnamespacestd;

constcharTab=0x9;

constintDIGIT=1;

constintMAXLEN=16384;

chars[MAXLEN],*endss;

intpcs=15;

doubleround(doubledVal, shortiPlaces) {//iPlaces>=0

chars[30];

doubledRetval;

sprintf(s,"%.*lf",iPlaces,dVal);

sscanf(s,"%lf",&dRetval);

return(dRetval);

}

doublefun(doublex,charop[],int*iop) {

while(op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>

switch(op[*iop-1]) {

case7: x=sin(x); (*iop)--;break;

case8: x=cos(x); (*iop)--;break;

case9: x=tan(x); (*iop)--;break;

case10: x=sqrt(x); (*iop)--;break;

case11: x=asin(x); (*iop)--;break;

case12: x=acos(x); (*iop)--;break;

case13: x=atan(x); (*iop)--;break;

case14: x=log10(x); (*iop)--;break;

case15: x=log(x); (*iop)--;break;

case16: x=exp(x); (*iop)--;break;

case17: x=ceil(x); (*iop)--;break;

case18: x=floor(x); (*iop)--;break;

case19: x=round(x,0);(*iop)--;break;

}

returnx;

}

doublecalc(char*expr,char**addr) {

staticintdeep; //递归深度

staticchar*fname[]={"sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp","ceil","floor","round",NULL};

doubleST[10]={0.0}; //数字栈

charop[10]={' '}; //运算符栈

charc,*rexp,*pp,*pf;

intist=1,iop=1,last,i;

if(!deep) {

pp=pf=expr;

do{

c = *pp ;

if(c!=' '&& c!=Tab)

*pf = c;

} while(c!='\0');

}

pp=expr;

if((c=*pp)=='-'||c==' ') {

op[0] = c;

pp ;

}

last = !DIGIT;

while((c=*pp)!='\0') {

if(c=='(') {//左圆括弧

deep ;

ST[ist ]=calc( pp,addr);

deep--;

ST[ist-1]=fun(ST[ist-1],op,&iop);

pp = *addr;

last = DIGIT;

if(*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是:当右圆括弧的右恻为左圆括弧或函数名字时,默认其为乘法

op[iop ]='*';

last = !DIGIT;

c = op[--iop];

gotooperate ;

}

}

elseif(c==')') {//右圆括弧

pp ;

break;

} elseif(isalpha(c)) {

if(!strnicmp(pp,"Pi",2)) {

if(last==DIGIT) {

cout<< "π左侧遇)"<<endl;exit(1);

}

ST[ist ]=3.14159265358979323846264338328;

ST[ist-1]=fun(ST[ist-1],op,&iop);

pp = 2;

last = DIGIT;

if(!strnicmp(pp,"Pi",2)) {

cout<< "两个π相连"<<endl;exit(2);

}

if(*pp=='(') {

cout<< "π右侧遇("<<endl;exit(3);

}

} else{

for(i=0; (pf=fname[i])!=NULL; i )

if(!strnicmp(pp,pf,strlen(pf))) break;

if(pf!=NULL) {

op[iop ] = 07 i;

pp = strlen(pf);

} else{

cout<< "陌生函数名"<<endl;exit(4);

}

}

} elseif(c==' '||c=='-'||c=='*'||c=='/'||c=='%'||c=='^') {

charcc;

if(last != DIGIT) {

cout<< "运算符粘连"<<endl;exit(5);

}

pp ;

if(c==' '||c=='-') {

do{

cc = op[--iop];

--ist;

switch(cc) {

case' ': ST[ist-1] = ST[ist];break;

case'-': ST[ist-1] -= ST[ist];break;

case'*': ST[ist-1] *= ST[ist];break;

case'/': ST[ist-1] /= ST[ist];break;

case'%': ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;

case'^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break;

}

} while(iop);

op[iop ] = c;

} elseif(c=='*'||c=='/'||c=='%') {

operate: cc = op[iop-1];

if(cc==' '||cc=='-') {

op[iop ] = c;

} else{

--ist;

op[iop-1] = c;

switch(cc) {

case'*': ST[ist-1] *= ST[ist];break;

case'/': ST[ist-1] /= ST[ist];break;

case'%': ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;

case'^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break;

}

}

} else{

cc = op[iop-1];

if(cc=='^') {

cout<< "乘幂符连用"<<endl;exit(6);

}

op[iop ] = c;

}

last = !DIGIT;

} else{

if(last == DIGIT) {

cout<< "两数字粘连"<<endl;exit(7);

}

ST[ist ]=strtod(pp,&rexp);

ST[ist-1]=fun(ST[ist-1],op,&iop);

if(pp == rexp) {

cout<< "非法字符"<<endl;exit(8);

}

pp = rexp;

last = DIGIT;

if(*pp == '('||isalpha(*pp)) {

op[iop ]='*';

last = !DIGIT;

c = op[--iop];

gotooperate ;

}

}

}

*addr=pp;

if(iop>=ist) {

cout<< "表达式有误"<<endl;exit(9);

}

while(iop) {

--ist;

switch(op[--iop]) {

case' ': ST[ist-1] = ST[ist];break;

case'-': ST[ist-1] -= ST[ist];break;

case'*': ST[ist-1] *= ST[ist];break;

case'/': ST[ist-1] /= ST[ist];break;

case'%': ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;

case'^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break;

}

}

returnST[0];

}

intmain(intargc,char**argv) {

inta;

if(argc<2) {

if(GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页

cout << "计算函数表达式的值。"<<endl<<"支持(), ,-,*,/,%,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp,ceil,floor,round"<<endl;

while(1) {

cout << "请输入表达式:";

gets(s);

if(s[0]==0) break;//

cout << s <<"=";

cout << setprecision(15) << calc(s,&endss) << endl;

}

} elseif(argc==2 && 0==strcmp(argv[1],"/?")) {

if(GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页

cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0~.15表示将计算结果保留小数0~15位"<<endl<<"支持(), ,-,*,/,%,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp,ceil,floor,round"<<endl;

} else{

strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;

if(argc>2) {

for(a=2;a<argc-1;a ) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s

if(1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0~.15表示将计算结果保留小数0~15位

printf("%.*lf\n",pcs,calc(s,&endss));

} else{

strncat(s,argv[a],MAXLEN-1);

printf("%.15lg\n",calc(s,&endss));

}

} else{

printf("%.15lg\n",calc(s,&endss));

}

}

return0;

}

希望能对大家有所帮助,也期待大家指出问题;

如果有对这方面有兴趣的可以加群:233026065,大家一起学习交流。

群内还有很多学习资料、书籍、视频,免费课等等......

.

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页