第一次写文章,这次写一个关于0-9计算器的C语言代码,不用栈。
具体流程是这样的,
第一步先输入一个算术表达式,必须是0-9的实数,运算符可以是+-*/^,然后分别用两个数组记录分割里面的数字和运算符,例如输入5+6.4/8--2^3/2,则数字数组为5,6.4,8,-2,3,2;运算符数组里存储的是+,/,-,^,/;
第二步循环遍历运算符数组,首先我们要知道运算符的优先级别,(^),(*和/),(+和-),因为'^'的优先级最高,所以先扫描数组中是否还存在 '^' 运算,如果有则锁定这个下标,调出数字数组里的这个下标的数和下一个下标的数进行运算,以上面为例,^的下标是3,则调出第3和第4下标的数字数组的值计算,也就是-2^3,结果为-8;
第三步是将运算过的数和运算符清除,运算符直接用循环覆盖清除即可,数字数组还需要将计算的值插入到该运算符下标位置下的数字数组里,以上面为例,即更新后的数字数组为5,6.4,8,-8,2,运算符数组为+,/,-,/;
第四步循环第二步和第三步,按优先级循环,直到运算符数组为空,输出数字数组里的数即为答案。
下面放代码和注释:
会用到的头文件和全局变量如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
float a[100];//记录数字,最多一百个数
char cal[100];//记录运算符(+-*/^)
int cl=0,al=0;//cl为运算符个数,al为数字个数
主函数如下:
int main()
{
char str[100];//定义一个字符串,记录表达式,最长为100
int i,j,k;
int n=0;
gets(str);//输入表达式
n=strlen(str);//表达式长度
for(i=0;i<n;i++)
{
//归类,符号放进cal数组,数字放在a数组
if(str[i]=='+'||str[i]=='*'||str[i]=='/'||str[i]=='^')
{
cal[cl++]=str[i];
}
else if(str[i]=='-')//'-'有两种情况,一种是代表符号加减,另一种代表负数
{
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
if(isdigit(str[i-1]))//说明是符号,而不是数字前的负号(-)
{
cal[cl++]=str[i];
}
else{
i++;
// a[al++]=atof(str[i+1]);
char s[20];
int t=0;
s[t++]=str[i];
if(str[i+1]=='.')//识别到小数点
{
s[t++]='.';
i++;
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
while(isdigit(str[i+1]))//直到碰到符号才停止赋值给临时变量s
{
s[t++]=str[i+1];
i++;
}
}
a[al++]=-1*atof(s);//将临时变量转化为浮点型并且变为相反数再赋值给a数组
memset(s,0,strlen(s));//格式化字符串
// i++;
}
}
else{
char s[20];
int t=0;
s[t++]=str[i];
if(str[i+1]=='.')//识别到小数点
{
s[t++]='.';//给临时变量赋值一个小数点
i++;
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
while(isdigit(str[i+1]))//直到碰到符号才停止赋值给临时变量s
{
s[t++]=str[i+1];
i++;
}
}
a[al++]=atof(s);//将临时变量转化为浮点型并且赋值给a数组
memset(s,0,strlen(s));//格式化字符串
}
}
/*
main函数开始到这,是对字符串
进行处理,将符号与数字分开
下面再调用calculate函数进行计算
并且输出结果
*/
// for(j=0;j<cl;j++)
// {
// printf("%c ",cal[j]);
// }
// printf("\n");
// for(k=0;k<al;k++)
// {
// printf("%g ",a[k]);
// }
// printf("\n");
calculate(str);
}
判断是否还有幂运算符号^:
int iscal1()//判断是否还有幂函数的符号'^'
{
int flag=0;
for(int i=0;i<cl;i++)
{
if(cal[i]=='^')
{
return 1;
}
}
return 0;
}
判断是否还有乘号和除号:
int iscal2()//判断是否还有乘法和除号的符号'*'及'/'
{
int flag=0;
for(int i=0;i<cl;i++)
{
if(cal[i]=='*'||cal[i]=='/')
{
return 1;
}
}
return 0;
}
计算函数:
void calculate(char str[])//计算函数
{
int i=0,j=0,k=0,t=0;
float temp;
while(cl)//当符号数组不空,也就是还是运算符时,则循环运行计算
{
if(iscal1())//首先判断幂运算,它的优先级最高
{
for(i=0;i<cl;i++)
{
if(cal[i]=='^')
{
temp=pow(a[i],a[i+1]);
for(j=i+1;j<al;j++)//数字数组减一 ,删掉已经运算过的数字
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)//符号数组减一,往前移,删掉已经算过的符号
{
cal[k]=cal[k+1];
}
cl--;
}
}
}
//以下计算的注释参照以上的if语句
else if(iscal2())//然后先乘除后加减
{
for(i=0;i<cl;i++)
{
if(cal[i]=='/'||cal[i]=='*')
{
if(cal[i]=='/')
{
temp=a[i]/a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
if(cal[i]=='*')
{
temp=a[i]*a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
}
}
}
else
{
for(i=0;i<cl;i++)
{
if(cal[i]=='+'||cal[i]=='-')
{
if(cal[i]=='+')
{
temp=a[i]+a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
if(cal[i]=='-')
{
temp=a[i]-a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
}
}
}
}
printf("%s=%g\n",str,a[0]);//%g格式可以输出标准数字,去掉零头
//比如34.630000,则输出34.63
}
其中我想细说一下主函数里刚开始的数字和运算符分割部分:
首先需要注意‘-’,它可能代表的是负号,也可能是减号。所以分割的时候需要区分一下,判断方法是判断它前面是不是数字字符,如果是,则它代表的是减号,反之则为负号。
其次就是小数的分割,分割方法是识别到存在小数点时,则循环遍历后面的字符,直到遇到运算符后就停止,我把这段代码单独放在下面吧。
识别'-'(识别负数也存在负小数的情况):
else if(str[i]=='-')//'-'有两种情况,一种是代表符号加减,另一种代表负数
{
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
if(isdigit(str[i-1]))//说明是符号,而不是数字前的负号(-)
{
cal[cl++]=str[i];
}
else{
i++;
// a[al++]=atof(str[i+1]);
char s[20];
int t=0;
s[t++]=str[i];
if(str[i+1]=='.')//识别到小数点
{
s[t++]='.';
i++;
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
while(isdigit(str[i+1]))//直到碰到符号才停止赋值给临时变量s
{
s[t++]=str[i+1];
i++;
}
}
a[al++]=-1*atof(s);//将临时变量转化为浮点型并且变为相反数再赋值给a数组
memset(s,0,strlen(s));//格式化字符串
// i++;
}
}
识别小数:
if(str[i+1]=='.')//识别到小数点
{
s[t++]='.';//给临时变量赋值一个小数点
i++;
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
while(isdigit(str[i+1]))//直到碰到符号才停止赋值给临时变量s
{
s[t++]=str[i+1];
i++;
}
}
接下来把全部代码呈上:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
float a[100];//记录数字,最多一百个数
char cal[100];//记录运算符(+-*/^)
int cl=0,al=0;//cl为运算符个数,al为数字个数
int iscal1()//判断是否还有幂函数的符号'^'
{
int flag=0;
for(int i=0;i<cl;i++)
{
if(cal[i]=='^')
{
return 1;
}
}
return 0;
}
int iscal2()//判断是否还有乘法和除号的符号'*'及'/'
{
int flag=0;
for(int i=0;i<cl;i++)
{
if(cal[i]=='*'||cal[i]=='/')
{
return 1;
}
}
return 0;
}
void calculate(char str[])//计算函数
{
int i=0,j=0,k=0,t=0;
float temp;
while(cl)//当符号数组不空,也就是还是运算符时,则循环运行计算
{
if(iscal1())//首先判断幂运算,它的优先级最高
{
for(i=0;i<cl;i++)
{
if(cal[i]=='^')
{
temp=pow(a[i],a[i+1]);
for(j=i+1;j<al;j++)//数字数组减一 ,删掉已经运算过的数字
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)//符号数组减一,往前移,删掉已经算过的符号
{
cal[k]=cal[k+1];
}
cl--;
}
}
}
//以下计算的注释参照以上的if语句
else if(iscal2())//然后先乘除后加减
{
for(i=0;i<cl;i++)
{
if(cal[i]=='/'||cal[i]=='*')
{
if(cal[i]=='/')
{
temp=a[i]/a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
if(cal[i]=='*')
{
temp=a[i]*a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
}
}
}
else
{
for(i=0;i<cl;i++)
{
if(cal[i]=='+'||cal[i]=='-')
{
if(cal[i]=='+')
{
temp=a[i]+a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
if(cal[i]=='-')
{
temp=a[i]-a[i+1];
for(j=i+1;j<al;j++)
{
a[j]=a[j+1];
}
a[i]=temp;
al--;
for(k=i;k<cl;k++)
{
cal[k]=cal[k+1];
}
cl--;
}
}
}
}
}
printf("%s=%g\n",str,a[0]);//%g格式可以输出标准数字,去掉零头
//比如34.630000,则输出34.63
}
int main()
{
char str[100];//定义一个字符串,记录表达式,最长为100
int i,j,k;
int n=0;
gets(str);//输入表达式
n=strlen(str);//表达式长度
for(i=0;i<n;i++)
{
//归类,符号放进cal数组,数字放在a数组
if(str[i]=='+'||str[i]=='*'||str[i]=='/'||str[i]=='^')
{
cal[cl++]=str[i];
}
else if(str[i]=='-')//'-'有两种情况,一种是代表符号加减,另一种代表负数
{
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
if(isdigit(str[i-1]))//说明是符号,而不是数字前的负号(-)
{
cal[cl++]=str[i];
}
else{
i++;
// a[al++]=atof(str[i+1]);
char s[20];
int t=0;
s[t++]=str[i];
if(str[i+1]=='.')//识别到小数点
{
s[t++]='.';
i++;
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
while(isdigit(str[i+1]))//直到碰到符号才停止赋值给临时变量s
{
s[t++]=str[i+1];
i++;
}
}
a[al++]=-1*atof(s);//将临时变量转化为浮点型并且变为相反数再赋值给a数组
memset(s,0,strlen(s));//格式化字符串
// i++;
}
}
else{
char s[20];
int t=0;
s[t++]=str[i];
if(str[i+1]=='.')//识别到小数点
{
s[t++]='.';//给临时变量赋值一个小数点
i++;
//isdight函数是ctype头文件里的函数
//用来判断字符是否为'0'~'9'
while(isdigit(str[i+1]))//直到碰到符号才停止赋值给临时变量s
{
s[t++]=str[i+1];
i++;
}
}
a[al++]=atof(s);//将临时变量转化为浮点型并且赋值给a数组
memset(s,0,strlen(s));//格式化字符串
}
}
/*
main函数开始到这,是对字符串
进行处理,将符号与数字分开
下面再调用calculate函数进行计算
并且输出结果
*/
// for(j=0;j<cl;j++)
// {
// printf("%c ",cal[j]);
// }
// printf("\n");
// for(k=0;k<al;k++)
// {
// printf("%g ",a[k]);
// }
// printf("\n");
calculate(str);
}
下面再放一个运行截图吧,就以刚开始那个例子:
如果对你有帮助的话评论区扣个1吧,哈哈,有问题也欢迎在评论区提出。