c语言可以编写计算程序吗,用c语言编写的可以计算+-*/的计算器

写了一个计算器程序,想分享给大家;同时写到最后感觉有点凌乱,希望各位帮忙给优化下,共同提高。这个计算器可以计算输入的字符串,字符串中可以含括号,可以是小数,也可以包含负数。此程序被拆分在5个文件中,我按文件一一罗列吧:

编写环境:VC++6.0。

第一个main函数所在文件:

#include

#include

#include

int main()

{

char *s1;

int i;

double c;

double calc(char *s);

int brk(char *st);

while(1)

{

s1=(char *)malloc(50);   //为s1分配地址和空间。

scanf("%s",s1);          //输入并得到s1字符串。

i=brk(s1);               //执行所有"()"中的计算式。

c=calc(s1);              //计算最后的不带"()"的s1。

printf("%g\n",c);        //输出最后结果。

printf("--------Press Up/Down Arorw or Begain Next Input:\n");

//提示执行下一次运算。

free(s1);    //释放s1内存空间。

}

}

第二个函数文件:

#include

#include

#include

double calc(char *s)   //把s拆解成double型数组和保存操作符的字符型数组,

{                      //并利用两个数组计算结果。

int i=0,j=0,k=0,num=1,end=0,sub=0;    //num、end、sub为开关标识。

double *sn;

char *sc,*sp;

void mathc(double *a,char *s);

sn=(double *)malloc(51);              //用于存放s中所有的数字串。

sc=(char *)malloc(50);                //用于存放s中所有的操作符。

sp=(char *)malloc(10);                //遍历s中的各个数字串,并保存其中。

//while(!isdigit(*s))

//    s++;

//c=*s;

//if(c=='-')

//{

//    *sp=c;

//    i=1;

//    s++;

//}

for(;*s!='\0';s++)                    //遍历s所有字符。

{

if(!isdigit(*s) && *s!='+' && *s!='-' && *s!='*' && *s!='/' &&

(接上一行) *s!='.')    //如果字符不是数字且不是操作符及小数点则输出错误。

{

printf("Error 6: illegal input!\n");

return 0;

}

if(isdigit(*s)||*s=='.')        //如果字符是个数字或者小数点。

{

//if(c=='-')

*(sp + i++)=*s;

//i++;

num=0;                      //把这3个开关置为0。

end=0;

sub=0;

continue;

}

if(sub==1)          //sub用于标识s中负数,比如"-5",

//但是如果有两个"--"则是错误,

// 除了类似"4--5"【等价于4-(-5)】的情况。

{               //"--"前没有数字的情况是不允许的。

printf("Error 7: too many operator!\n");

return 0;

}

if(num==1)          //num==1说明是字符串刚开始(即第一个字符)

{                   //或者上一次执行的是“+-*/”。

if(*s!='-')     //开始不是"-"或"+*/"后面不是"-"。

{               //(注意在这个时候肯定也不是数字,

//因为数字已经被判断过了。)

printf("Error 8: too many operator!\n");

return 0;

}

else

{

*(sp + i++)=*s;     //开始是个"-"或者前一个字符是"+*/"。

sub=1;              //把sub置为1,即下一个字符不能再是"-",

//注意这是在num==1的情况下。

end=0;              //执行的是数字字符部分,此程序把

//这种情况下的负号做为了数字的一部分。

continue;           //执行下一次循环。

}

}

if(*s=='+'||*s=='-'||*s=='*'||*s=='/')  //如果执行的字符是操作符。

{

*(sp+i)='\0';                     //是sp结束,即结束数字字符部分。

i=0;                              //使下一次sp从0开始计数。

end=1;                            //标识数字字符部分执行结束。

*(sn + j++)=atof(sp);             //把sp转换为double型数组。

if(*(s+1)=='\0')                  //如果下一个元素为s的的结束,

//则不往下执行,即不保存这个操作符。

break;

*(sc + k++)=*s;                   //既然s的下一个元素不是结束,

//那么把这个字符串保存到sc中。

num=1;                            //因为刚保存的是个操作符,

//下一个不能再是操作符,除了"-"。

continue;

}

}

if(*s=='\0'&&end==0)            //s的最后一个字符是数字字符,执行这一部分语句。

{

*(sp+i)='\0';               //使sp结束。

//i=0;

if(*(sp+i-1)=='-')          //如果上一个字符只是一个"-"号,则输出错误。

{

printf("Error 9: illegal input!\n");

return 0;

}

*(sn + j++)=atof(sp);        //把sp转换成double数组保存到sn中。

}

*(sn+j)='\0';                    //是sn和sc结束。

*(sc+k)='\0';

mathc(sn,sc);                    //把sn和sc传给mathc函数计算s的结果。

return *sn;                      //mathc的计算结果是保存在sn中的,

}                                    //把sn返回即可。

第三个函数文件:

#include

void mathc(double *a, char *s)                            //执行计算。

{

int i;

double sum;

void offsetd(double *s,int n1, int n2);

void offsetc(char *s,int n1,int n2);

for(i=0;*(s+i)!='\0';i++)                            //先计算“/”。

if(*(s+i)=='/')

{

if(*(a+i+1)==0)                                //不能除以0。

{

printf("Error 5: illegal input 0!\n");

break;

}

sum = *(a+i) / *(a+i+1);

*(a+i)=sum;

offsetd(a,i+1,1);

offsetc(s,i,1);

i=-1;

}

for(i=0;*(s+i)!='\0';i++)                            //计算"*"。

if(*(s+i)=='*')

{

sum = *(a+i) * *(a+i+1);

*(a+i)=sum;

offsetd(a,i+1,1);

offsetc(s,i,1);

i=-1;

}

for(i=0;*(s+i)!='\0';i++)                            //计算"-"。

if(*(s+i)=='-')

{

sum = *(a+i) - *(a+i+1);

*(a+i)=sum;

offsetd(a,i+1,1);

offsetc(s,i,1);

i=-1;

}

for(i=0;*(s+i)!='\0';i++)                            //计算"+"。

if(*(s+i)=='+')

{

sum = *(a+i) + *(a+i+1);

*(a+i)=sum;

offsetd(a,i+1,1);

offsetc(s,i,1);

i=-1;

}

}

第四个函数文件:

#include

#include

void offsetd(double *s,int n1, int n2) //使double数组的n1+n2处的元素往前移动n2。

{

for(;*(s+n1)!='\0';n1++)

*(s+n1) = *(s+n1+n2);

}

void offsetc(char *s,int n1, int n2)   //与offsetd功能相同,只是s数组元素是字符型。

{

for(;*(s+n1)!='\0';n1++)

*(s+n1) = *(s+n1+n2);

}

void repl(char *c1,char *c2,int i,int j) //使用c2替换c1中第i-j之间的元素。

{

unsigned int n=0;

int a;

n=strlen(c2);

for(a=n;*(c1+j)!='\0';)             //先把c1中第j元素以后的数字复制到c2后面。

*(c2 + a++) = *(c1 + j++);

*(c2+a)='\0';

for(;*c2 != '\0';)                 //用c2替换c1中第i元素往后的所有元素。

*(c1 + i++) = *(c2++);

*(c1+i)='\0';

}

第五个函数文件:

#include

#include

#include

int brk(char *st)    //计算括号内的算式的值。

{

int m,n,d,b;     //m左括号位置,n遍历整个st数组,d右括号位置,b用于上s2数组。

char *s2;

double i;

void repl(char *c1,char *c2,int i,int j);  //调用repl函数使用s2计算结果

//替换st中相应位置的字符。

//void mathc(double *a,char *s);

double calc(char *s);                      //计算字符串s的值。

s2=(char *)malloc(50);            //为s2分配内存空间,并返回空间地址。

for(n=0;*(st+n)!='\0';n++)        //遍历st数组。

if(*(st+n)==')')              //首先查找")"。重要!在多重括号

//中查找")"才能有效的找到每组括号。

{    d=n;                     //把"("的位置保存在d中。

if(*(st+d+1)!='\0'&&isdigit(*(st+d+1))) //st的下一位是个数字则

//输出错误并返回。

{

printf("Error 1: ();\n");

return 0;

}

while(n>0&&*(st + --n)!='(')      //从")"的位置n往回查找"("。

;

if(*(st+n)!='(')           //while语句执行完成,此时n==0;

//但是*(st+n)不是"(",则意味着没有匹配的

//"(",输出错误。

{

printf("Error 2: ();\n");

return 0;

}

m=n;                        //找到"("的话,把n的值保存到m中。

if(m>0 && isdigit(*(st+m-1)))  //m位置的上一位不能是数字。

{

printf("Error 3: ();\n");

return 0;

}

if((d-m)==1)                   //如果"()"为空,输出错误。

{

printf("Error 4: ();\n");

return 0;

}

for(b=0;*(st + ++n)!=')';b++)  //把括号中的内容复制到s2中。

*(s2+b) = *(st + n);

*(s2+b)='\0';

i=calc(s2);                    //计算s2的值,并返回double i。

sprintf(s2,"%g",i);            //把i转换成字符串保存至s2中。

//printf("s2 %s\n",s2);

repl(st,s2,m,n+1);             //使用s2替换st中的括号。

printf("step %s\n",st);        //输出替换后的st。

n=-1;                          //执行下一次循环。

continue;

}

}

写的不好,大神勿喷,欢迎指正。

欢迎转载,但是版权所有。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值