系本人原创,转载请注明地址https://blog.csdn.net/coder_what/article/details/82682366
本人大一菜鸡一枚,借着老师课程设计的机会,用C语言写了一个四则运算
(即输入一个字符串,返回它计算的结果)
实现的功能或者难点有以下几个:
1. 连续运算
2. 识别数字和运算符以及括号
3. 乘法/除法和括号优先级的问题
4. 把带小数的字符串转换成数字
对于第一个问题:
用一个while循环,当字符串到结尾时结束循环就OK了
对于第二个问题:
这里用的是if和for语句,注意一定要加单引号,如:
for(;s[i]<='9'&&s[i]>='0';i++)
对于第三个问题:
先算乘法和除法,把算完的结果储存在一个float类型的数组里面,把遇到的加号和减号放在一个字符数组里,最后再算加减法。当遇到括号时,运用递归的思想,先算出最里面的括号,依次算外面的,再进行下一组运算
这里其实还有一个问题,就是如何找到最里面的括号,又如何准确的识别并保存括号里面的数呢?当出现括号内出现多个平级括号又该怎么处理呢?
我用的方法就是用count_r和count_l计算左右两边括号的数目,从左边第一个括号开始,当右边的括号大于左边的括号时,就证明已经把里面的括号遍历完毕,就可以愉快的计算啦。
对于第四个问题:
计算小数点前的数时:
for(;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
计算小数点后面的数时:
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
最后结果就是x+y了。
需要注意的是x和y在每次计算前必须重新赋值为零,且tem_y必须重新赋值为1
先放上头文件和全局变量
//头文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//全局变量
int i,n,x,sum,y;
char s[80];
char s1[80];
char s2[80];
逐步实现功能,先放一个连续整数加法的源码:
x=0,sum=0,i=0;
printf("\n\t\tPlease input the numbers which you want to calculate:");
scanf("%s",s);
while(s[i]!='\0')
{
for(;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='+'||s[i]=='\0')
{
i++;
sum+=x;
x=0;
}
else
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return;
}
}
printf("\t\t\t %s = %d\n",&s,sum);
当进行除法时,要考虑除数为零的问题,并且必须要先计算第一个数,放一个连续整数除法的源码:
float sum,x=0;
i=0;
printf("\n\t\tPlease input the numbers which you want to calculate:");
scanf("%s",s);
for(i=0;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
sum=x;
while(1)
{
x=0;
if(s[i]=='\0')
break;
if(s[i]!='/')
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return;
}
i++;
for(;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(x!=0)
sum=sum/x;
else
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return;
}
}
printf("\t\t%s = %.2lf\n",&s,sum);
现在可以试试整数的不带括号的四则运算了:
float number[80],x;
int len,j=0,k=0;
char operat[80];
printf("\n\t\tPlease input the numbers which you want to calculate:");
scanf("%s",s);
len=strlen(s);
for(i=0;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
j++;
for(;i<len;)
{
if(s[i]=='*')
{
x=0;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
number[j-1]=number[j-1]*number[j];
}
if(s[i]=='/')
{
x=0;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
if(number[j]==0)
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return;
}
number[j-1]=number[j-1]/number[j];
}
if(s[i]=='+'||s[i]=='-')
{
operat[k]=s[i];
k++;
x=0;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
j++;
}
}
for(i=0;i<k+j;i++)
{
if(operat[i] == '+')
{
number[0] += number[i+1];
continue;
}
if(operat[i]=='-')
{
number[0] -= number[i+1];
continue;
}
}
printf("\t\t\t %s = %.2f\n",&s,number[0]);
要注意乘法和除法中的 number[j-1]=number[j-1]*number[j];
因为是直接算出来,所以就代替了前一个数
来试试带一个括号的整数运算,此处需要加一个辅助函数(基于主函数)
int main()
{
float number[80],x=0;
int len,j=0,k=0,l,tem_j,tem_k,tem_i;
char operat[80],s1[80];
printf("\n\t\tPlease input the numbers which you want to calculate:");
scanf("%s",s);
len=strlen(s);
if(s[0]=='(')
{
for(i=1,l=0;s[i]!=')';i++,l++)
s1[l]=s[i];
s1[l]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=mixmodel(s1);
j=tem_j;
k=tem_k;
i=++tem_i;
}
else
{
i=0;
for(;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
}
j++;
for(;i<len;)
{
if(s[i]=='*')
{
if(s[i+1]=='(')
{
for(i+=2,l=0;s[i]!=')';l++,i++)
s1[l]=s[i];
s1[i]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=mixmodel(s1);
i=++tem_i;
j=tem_j;k=tem_k;
}
else
{
x=0;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
}
number[j-1]=number[j-1]*number[j];
}
if(s[i]=='/')
{
if(s[i+1]=='(')
{
for(i+=2,l=0;s[i]!=')';i++,l++)
s1[l]=s[i];
s1[l]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=mixmodel(s1);
i=++tem_i;
j=tem_j;k=tem_k;
}
else
{
x=0;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
}
if(number[j]==0)
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return 0;
}
number[j-1]=number[j-1]/number[j];
}
if(s[i]=='+'||s[i]=='-')
{
operat[k]=s[i];
k++;
if(s[i+1]=='(')
{
for(i+=2,l=0;s[i]!=')';i++,l++)
s1[l]=s[i];
s1[l]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=mixmodel(s1);
i=++tem_i;
j=++tem_j;k=tem_k;
}
else
{
x=0;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
number[j]=x;
j++;
}
}
}
for(i=0;i<j+k;i++)
{
if(operat[i] == '+')
{
number[0] += number[i+1];
continue;
}
if(operat[i]=='-')
{
number[0] -= number[i+1];
continue;
}
}
printf("\t\t\t %s = %.2f\n",&s,number[0]);
return 0;
}
float mixmodel(char*s1)
{
float number[80],x=0;
int len,j=0,k=0;
char operat[80];
len=strlen(s1);
for(i=0;s1[i]<='9'&&s1[i]>='0';i++)
x=(s1[i]-'0')+x*10;
number[j]=x;
j++;
for(;i<len;)
{
if(s1[i]=='*')
{
x=0;
for(i++;s1[i]<='9'&&s1[i]>='0';i++)
x=(s1[i]-'0')+x*10;
number[j]=x;
number[j-1]=number[j-1]*number[j];
}
if(s1[i]=='/')
{
x=0;
for(i++;s1[i]<='9'&&s1[i]>='0';i++)
x=(s1[i]-'0')+x*10;
number[j]=x;
if(number[j]==0)
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return 0;
}
number[j-1]=number[j-1]/number[j];
}
if(s1[i]=='+'||s1[i]=='-')
{
operat[k]=s1[i];
k++;
x=0;
for(i++;s1[i]<='9'&&s1[i]>='0';i++)
x=(s1[i]-'0')+x*10;
number[j]=x;
j++;
}
}
for(i=0;i<k+j;i++)
{
if(operat[i] == '+')
{
number[0] += number[i+1];
continue;
}
if(operat[i]=='-')
{
number[0] -= number[i+1];
continue;
}
}
return number[0];
tem_i,tem_j,tem_k分别是用来暂时储存i,j,k的数值的
最后放大招,试试带多级括号的实数四则运算吧:
int main()
{
float number[80],x=0,y=0,tem_y=1;
int len,i=0,j=0,k=0,l=0,count_r=0,count_l=0,tem_j,tem_k,tem_i;
char operat[80],s[80],s1[80];
printf("Please input the numbers which you want to calculate:");
scanf("%s",s);
len=strlen(s);
if(s[0]=='(')
{
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r||count_l==0))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=tem_j;
k=tem_k;
i=++tem_i;
}
else
{
i=0;
for(;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
number[j]=x+y;
}
j++;
for(;i<len;)
{
if(s[i]=='*')
{
if(s[i+1]=='(')
{
i++;
l=0;
count_l=count_r=0;
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r||count_l==0))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=tem_j;
k=tem_k;
i=++tem_i;
}
else
{
x=0;y=0;tem_y=1;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
number[j]=x+y;
}
number[j-1]=number[j-1]*number[j];
}
if(s[i]=='/')
{
if(s[i+1]=='(')
{
i++;
l=0;
count_l=count_r=0;
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r||count_l==0))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=tem_j;
k=tem_k;
i=++tem_i;
}
else
{
x=0;y=0;tem_y=1;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
number[j]=x+y;
}
if(number[j]==0)
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return 0;
}
number[j-1]=number[j-1]/number[j];
}
if(s[i]=='+'||s[i]=='-')
{
operat[k]=s[i];
k++;
if(s[i+1]=='(')
{
i++;
l=0;
count_l=count_r=0;
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r||count_l==0))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=++tem_j;
k=tem_k;
i=++tem_i;
}
else
{
x=0;y=0;tem_y=1;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
number[j]=x+y;
j++;
}
}
}
for(i=0;i<j+k;i++)
{
if(operat[i] == '+')
{
number[0] += number[i+1];
continue;
}
if(operat[i]=='-')
{
number[0] -= number[i+1];
continue;
}
}
printf("\t\t\t %s = %.2f\n",&s,number[0]);
system("pause");
return 0 ;
}
float aux(char*s)
{
float number[80],x=0,y=0,tem_y=1;
int len,i=0,j=0,k=0,l=0,count_r=0,count_l=0,tem_j,tem_k,tem_i;
char operat[80],s1[80];
len=strlen(s);
if(s[0]=='(')
{
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=tem_j;
k=tem_k;
i=++tem_i;
}
else
{
i=0;
for(;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y=0.1*tem_y;
}
number[j]=x+y;
}
j++;
for(;i<len;)
{
if(s[i]=='*')
{
if(s[i+1]=='(')
{
i++;
l=0;
count_l=count_r=0;
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r||count_l==0))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=tem_j;
k=tem_k;
i=++tem_i;
}
else
{
x=0;y=0;tem_y=1;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
number[j]=x+y;
}
number[j-1]=number[j-1]*number[j];
}
if(s[i]=='/')
{
if(s[i+1]=='(')
{
i++;
l=0;
count_l=count_r=0;
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r||count_l==0))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=tem_j;
k=tem_k;
i=++tem_i;
}
else
{
x=0;y=0;tem_y=1;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
number[j]=x+y;
}
if(number[j]==0)
{
printf("\n\t\tThe operator is error!\n");
system("pause");
return 0;
}
number[j-1]=number[j-1]/number[j];
}
if(s[i]=='+'||s[i]=='-')
{
operat[k]=s[i];
k++;
if(s[i+1]=='(')
{
i++;
l=0;
count_l=count_r=0;
while(1)
{
i++;
if(s[i]=='(')
count_l++;
s1[l]=s[i];
l++;
if(s[i]==')')
count_r++;
if(s[i]==')'&&(count_l<count_r||count_l==0))
break;
}
s1[l-1]='\0';
tem_j=j;tem_k=k;tem_i=i;
number[tem_j]=aux(s1);
j=++tem_j;
k=tem_k;
i=++tem_i;
}
else
{
x=0;y=0;tem_y=1;
for(i++;s[i]<='9'&&s[i]>='0';i++)
x=(s[i]-'0')+x*10;
if(s[i]=='.')
for(i++;s[i]<='9'&&s[i]>='0';i++)
{
y=(s[i]-'0')*0.1*tem_y+y;
tem_y*=0.1;
}
number[j]=x+y;
j++;
}
}
}
for(i=0;i<j+k;i++)
{
if(operat[i] == '+')
{
number[0] += number[i+1];
continue;
}
if(operat[i]=='-')
{
number[0] -= number[i+1];
continue;
}
}
operat[0]=0;
return number[0];
}
这种情况下主要加了一个对多级括号的处理,当s1读取括号里的字符串时,如果右面的括号多于左边的括号,则读取字符串完毕,注意在下一次读取时要把运算符数组(operat)和左右括号的计数(count_l,count_r)重新变成0