据我验证 codeblocks 的ascii码在128后就不能输出 ,又因为在此之前代码是加上了48 ,所以一旦超过80 ,就输出错误 , 输出的是 (原本的答案 - 256),比如本来应该是120, 最后输出的结果会是 120 - 256= - 136,当然如果codeblocks的版本不一样可能结果不同 , 我的版本是Release 17.12 rev 11256 (2017-12-28 10:44:41) gcc 5.1.0 Windows/unicode - 32 bit。
#include<stdio.h>
#include<stdlib.h>
#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char ElemType;
typedef int Status;
typedef char OperandType;
typedef char OperatorType;
typedef struct
{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
Status InitStack(SqStack *S)
{
(*S).base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
if(!(*S).base) exit(OVERFLOW);
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
return OK;
}
Status Gettop(SqStack S,ElemType *e)
{
if(S.top==S.base) return ERROR;
*e=*(S.top-1); return OK;
}
OperandType GetTop(SqStack S)
{
ElemType e;
Gettop(S,&e);
return e;
}
Status Push(SqStack *S,ElemType e)
{
if(((*S).top-(*S).base)>=(*S).stacksize)
{
(*S).base=(ElemType *)realloc((*S).base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(ElemType));
if(!(*S).base) exit(OVERFLOW);
(*S).stacksize+=STACKINCREMENT;
(*S).top=(*S).base+(*S).stacksize;
}
*((*S).top++)=e;
return OK;
}
Status Pop(SqStack *S,ElemType *e)
{
if((*S).base==(*S).top) return ERROR;
*e=*(--(*S).top);
return OK;
}
Status In(char c)
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '#':
return TRUE;
break;
default:
return FALSE;
break;
}
}
OperandType Operate(OperandType a,OperatorType c,OperandType b)
{
int x,y; //0的ascii码是48
//这是错误的写法 如果是数字0-9那么没有问题 但是这里是可能14 20就不能这样了
//x=a-'0';
//y=b-'0';
x=a-48;
y=b-48;
//直接用数字是没有问题的
switch(c)
{
case '+':
return x+y+48;
break;
case '-':
return x-y+48;
break;
case '*':
return x*y+48;
break;
case '/':
return x/y+48;
break;
}
}
OperatorType Precede(OperatorType e1,OperatorType e2) //数据结构p53页表格
{
OperatorType f;
switch(e2)
{
case '+':
case '-':
if(e1=='('||e1=='#')
f='<';
else f='>';
break;
case '*':
case '/':
if(e1=='*'||e1=='/'||e1==')')
f='>';
else f='<';
break;
case '(':
if(e1==')')
{
printf("括号匹配错误\n");
exit(-1);
}
else f='<';
break;
case ')':
switch(e1)
{
case '(':
f='=';
break;
case '#':
printf("输出了错误的括号\n");
exit(-1);
break;
default:
f='>';
break;
}
break; //刚开始这里忘记了break
case '#':
switch(e1)
{
case '#':
f='=';
break;
case '(':
printf("括号匹配错误\n");
exit(-1);
break;
default:
f='>';
break;
}
break; //case中的break只跳出小switch,在这种情况下会继续向大switch下比较
}
return f;
}
OperandType EvaluateExpression(char *exp)
{
SqStack OPTR; //运算符栈
InitStack(&OPTR);
Push(&OPTR,'#');
SqStack OPND; //运算数栈
InitStack(&OPND);
char ch;
int i=0;
ch=exp[i++];
OperandType a,b; //运算数类型
OperatorType c,e; //运算符类型
while(ch!='#'||GetTop(OPTR)!='#') //刚开始这里符号错误处理成了&&根本进不了循环 直接返回的就是#的ascii码是35 //GetTop(OPTR)!='#'是避免第一个数输入的就是运算符
{
if(!In(ch))
{
Push(&OPND,ch);
ch=exp[i++];
}
else
{
switch(Precede(GetTop(OPTR),ch))
{
case '<':
Push(&OPTR,ch);
ch=exp[i++];
break;
case '=':
Pop(&OPTR,&e);
ch=exp[i++];
break;
case '>': //这里没有输入字符,保留的是刚刚的字符
Pop(&OPTR,&c);
Pop(&OPND,&b);
Pop(&OPND,&a);
Push(&OPND,Operate(a,c,b)); //这个地方顺序不能反 比如5-6哈 存进去是5 6 出来应该是6 5
break;
}
}
}
return GetTop(OPND);
}
int main()
{
char n;
char *exp="3*(7-2)+8#"; //因为我输入的时候输入完#号后没有结果,所以我采用的这种方法,只需要将函数中的ch=getchar();换成ch=exp[i++]
n=EvaluateExpression(exp);
printf("作为示例,%s 的计算结果为:%d\n",exp,n-48);
return 0;
//char *exp = "(2+3)*4*6#";
//这个的输出结果一直都是-136,奇奇怪怪
//我当时的想法就是120+48后是168 超过了128范围 所以出错了
//char *exp="3*(7-2)*9#";
//这个结果是-121 本来结果应该是135 135+|-121|=256
//char *exp="3*(7-2)*8#";
//这个结果是-136 本来结果是120 120+|-136|=256
//据我验证 128后就不能输出 在此之前是加上了48 所以超过80 就输出错误 输出的是 (原本的答案-256)
//char *exp="9*9#" 就是81-256=-175
}
//#include<stdio.h>
//int main()
//{
// int a=168;
// printf("%c",a);
// return 0;
//}
//127的ascii码 在控制台输出时我没有看到 但是复制粘贴输出结果的时候出现了这个 太神奇了吧
//
//Process returned 0 (0x0) execution time : 1.412 s
//Press any key to continue.
//128的ascii码 我居然在控制台看到了这样原封不动的样子
//€
//Process returned 0 (0x0) execution time : 0.105 s
//Press any key to continue.
//129的时候就没有输出了
//Process returned 0 (0x0) execution time : 0.099 s
//Press any key to continue.
测试结果:
作为示例,3*(7-2)+8# 的计算结果为:23
Process returned 0 (0x0) execution time : 0.104 s
Press any key to continue.