C语言 计算器问题(请大神看一下)
123+213-67*34+345/23*45*(34+34-345+245+567)=359 183
可我的程序等于-363067 代码如下
#include
#include
#include
#define MAXZISE 1000
struct oper
{
char name;
int priority;
int opnum;
};
typedef struct oper OPERATOR;
OPERATOR opStack[MAXZISE];
int OTop=-1;
int numStack[MAXZISE];
int NTop=-1;
int getPriority(char name)//获取一个字符所代表的运算符的优先级
{
if (name=='('||name==')'){
return 0;
}
if (name=='*'||name=='/'){
return 2;
}
if (name=='+'||name=='-'){
return 1;
}
}
int getOpNum(char name)//获取一个字符所代表的运算符的目数
{
if (name=='*'||name=='/'||name=='+'||name=='-'){
return 2;
}
if (name=='('||name==')'){
return 0;
}
}
void pushOp(OPERATOR op)//运算符压栈
{
if (OTop
opStack[++OTop] = op;
}
}
OPERATOR popOp()//运算符出栈
{
if (OTop>= 0){
return opStack[OTop--];
}
}
void pushNum(int num)//操作数压栈
{
if (NTop
numStack[++NTop] = num;
}
}
int popNum()//操作数出栈
{
if (NTop >= 0){
return numStack[NTop--];
}
}
int change(char s, int *i)//将数字从字符串转换到整型
{
int j = 0;
char str[MAXZISE];
while ((*s) >= '0' && *s <= '9')
{
str[j++] = (*s);
s++;
}
(*i) = (*i) + j;
str[j] = '\0';
return atoi(str);
}
int opertateNum(OPERATOR op)//从操作数栈中弹出两个操作数,完成一次双目运算
{
int num2=popNum();
int num1=popNum();
if (op.name=='+'){
return num1 + num2;
}
if (op.name=='-'){
return num1 - num2;
}
if (op.name==''){
return num1 * num2;
}
if (op.name=='/'){
return num1 / num2;
}
}
int main()
{
char S[MAXZISE];
int i,j;
OPERATOR op, topOp;
topOp.name = '#';
topOp.priority = 0;
topOp.opnum = 0;
pushOp(topOp);
scanf("%s", S);
for(i=0;i
if(S[i]!=' ')
S[j++]=S[i];
}
S[j]='\0';
for (i=0;S[i]!='\0'&&S[i]!='=';){
if (S[i]>='0'&&S[i]<='9'){
pushNum(change(&S[i], &i));
}
else{
op.name = S[i];
op.priority = getPriority(S[i]);
op.opnum = getOpNum(S[i]);
topOp = popOp();
if (op.name == '('){
//如果是'(',将从栈顶弹出的运算符压回栈内,并将当前运算符则压栈
pushOp(topOp);
pushOp(op);
}
else if (op.name == ')'){
//如果是')',则进行运算,每次运算结果作为一个操作数压入操作数栈,直到将'('弹出运算符栈
while (topOp.name != '('){
pushNum(opertateNum(topOp));
topOp = popOp();
}
}
else{
if (topOp.name !='#'&& op.priority<= topOp.priority){
pushNum(opertateNum(topOp));
}
else{
pushOp(topOp);
}
pushOp(op);
}
i++;
}
}
while ((topOp = popOp()).name!='#'){
pushNum(opertateNum(topOp));
}
printf("%d\n", popNum());
return 0;
}
谢谢大家帮忙,程序我已经调出来了
问题在于运算符的入栈与出栈,碰到 - * + 时,有点小问题,应该继续比较优先级。
正确代码如下:
#include
#include
#include
#define MAXZISE 100
struct oper
{
char name;
int priority;
int opnum;
};
typedef struct oper OPERATOR;
OPERATOR opStack[MAXZISE];
int OTop=-1;
int numStack[MAXZISE];
int NTop=-1;
void pushOp(OPERATOR op)//运算符压栈
{
if (OTop
opStack[++OTop] = op;
}
}
OPERATOR popOp()//运算符出栈
{
if (OTop>= 0){
return opStack[OTop--];
}
}
void pushNum(int num)//操作数压栈
{
if (NTop
numStack[++NTop] = num;
}
}
int popNum()//操作数出栈
{
if (NTop >= 0){
return numStack[NTop--];
}
}
int getPriority(char name)//获取一个字符所代表的运算符的优先级
{
if (name=='('||name==')'){
return 0;
}
if (name=='*'||name=='/'){
return 3;
}
if (name=='-'||name=='+'){
return 2;
}
}
int getOpNum(char name)//获取一个字符所代表的运算符的目数
{
if (name=='*'||name=='/'||name=='+'||name=='-'){
return 2;
}
if (name=='('||name==')'){
return 0;
}
}
int change(char s, int *i)//将数字从字符串转换到整型
{
int j = 0;
char numstr[MAXZISE];
while ((*s) >= '0' && *s <= '9')
{
numstr[j++] = (*s);
s++;
}
(*i) = (*i) + j;
numstr[j] = '\0';
return atoi(numstr);
}
int opertateNum(OPERATOR op)//从操作数栈中弹出两个操作数,完成运算
{
int num2=popNum();
int num1=popNum();
if (op.name=='+'){
return num1 + num2;
}
if (op.name=='-'){
return num1 - num2;
}
if (op.name==''){
return num1 * num2;
}
if (op.name=='/'){
return num1 / num2;
}
}
int main()
{
char S[MAXZISE];
int i,j;
OPERATOR op,topOp;
topOp.name='#';
topOp.priority=0;
topOp.opnum=0;
pushOp(topOp);
gets(S);
for(i=0;i
if(S[i]!=' ')
S[j++]=S[i];
}
S[j]='\0';
for(i=0; S[i]!='\0'&&S[i]!='=';){
if (S[i]>='0'&&S[i]<='9'){
pushNum(change(&S[i], &i));
}
else{
op.name=S[i];
op.priority=getPriority(S[i]);
op.opnum=getOpNum(S[i]);
topOp=popOp();
if (op.name=='('){
//如果是'(',将从栈顶弹出的运算符压回栈内,并将当前运算符则压栈
pushOp(topOp);
pushOp(op);
}
else if(op.name==')'){
//如果是')',则进行运算,每次运算结果作为一个操作数压入操作数栈,直到将'('弹出运算符栈
while (topOp.name!='('){
pushNum(opertateNum(topOp));
topOp=popOp();
}
}
else{
while(topOp.name !='#'&& op.priority<= topOp.priority){
pushNum(opertateNum(topOp));
topOp=popOp();
}
if(topOp.name =='#'|| op.priority> topOp.priority){
pushOp(topOp);
}
pushOp(op);
}
i++;
}
}
while ((topOp=popOp()).name!='#'){
pushNum(opertateNum(topOp));
}
printf("%d\n", popNum());
return 0;
}
进行改动的代码是这几行:
while(topOp.name !='#'&& op.priority<= topOp.priority){
pushNum(opertateNum(topOp));
topOp=popOp();
}
if(topOp.name =='#'|| op.priority> topOp.priority){
pushOp(topOp);
}
帮楼主调试了下发现
对于123+213-67*34+345/23*45*(34+34-345+245+567)类似这样的式子
它会计算成123+213-((67*34+345/23*45*(34+34-345+245+567)))=-363067
建议楼主检查下逻辑,或者单步调试看看
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
#include stdio.h
int mian
void main返回最后的值/n回车键返回
i++;
return 0;