首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

表达式求值的一个有关问题

2012-03-06 
表达式求值的一个问题这个星期我做了一个表达式求值的程序(输入、输出和中间结果均只能是0~9):大概是这样的

表达式求值的一个问题
这个星期我做了一个表达式求值的程序(输入、输出和中间结果均只能是0~9):
大概是这样的:输入一个中序表达式,用一个转换程序变为后序表达式,再对后序表达式求值,这两个子程序我都做出来了然后是主程序:我将转换出来的后序表达式存储再一个数组里,将数组头指针传递给求值程序,但就是这里出错了。希望高手指教!谢谢!!

#define   STACK_INIT_SIZE   20
#define   STACKINCREMENT   2
typedef   char   SElemType;
typedef   struct   SqStack{              
        SElemType   *base;
        SElemType   *top;
        int   stacksize;
}SqStack;

Status   InitStack(SqStack   *S){                   /*初始化栈     */
        (*S).base   =   (SElemType   *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
        if(!(*S).base)
exit(OVERFLOW);
        (*S).top   =   (*S).base;
        (*S).stacksize   =   STACK_INIT_SIZE;
        return   OK;
}

char   GetTop(SqStack   S){                 /*取栈顶元素     */
        if(S.top   ==   S.base)
return   ERROR;
        return   *(S.top   -   1);
}

Status   Push(SqStack   *S,SElemType   e){           /*入栈       */
        if((*S).top   -   (*S).base   > =   (*S).stacksize){
(*S).base   =   (SElemType   *)realloc((*S).base,
  ((*S).stacksize   +   STACKINCREMENT)   *   sizeof

(SElemType));
if   (!(*S).base)
        exit   (OVERFLOW);
(*S).top   =   (*S).base   +   (*S).stacksize;
(*S).stacksize   +=   STACKINCREMENT;
        }
        *((*S).top)++   =   e;
        return   OK;
}

char   Pop(SqStack   *S,SElemType   *e){       /*出栈     */
        if((*S).top   ==   (*S).base)
return   ERROR;
        *e   =   *   --(*S).top;
        return   *e;
}

Status   In(char   c){                   /*判断是否为运算符   */
        int   i;
        int   j   =   0;
        char   OP[]   =   { '+ ',   '- ',   '* ',   '/ ',   '( ',   ') ',   '# '};
        for   (i   =   0;   i   <=   6;   i++){
if   (c   ==   OP[i])
        j++;
        }
        if   (j)
return   TRUE;
        else
return   FALSE;
}

char   Precede(char   opnd1,   char   opnd2){       /*运算符优先级   */
        int   i,   j;
        char   guanxi[7][7]={           '> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',
                                        '> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',


                                        '> ', '> ', '> ', '> ', ' < ', '> ', '> ',
                                        '> ', '> ', '> ', '> ', ' < ', '> ', '> ',
                                        ' < ', ' < ', ' < ', ' < ', ' < ', '= ', '   ',
                                        '> ', '> ', '> ', '> ', '   ', '> ', '> ',
        ' < ', ' < ', ' < ', ' < ', ' < ', '   ', '= '};
        switch(opnd1){
  case   '+ ':   i   =   0;break;
  case   '- ':   i   =   1;break;
  case   '* ':   i   =   2;break;
  case   '/ ':   i   =   3;break;
  case   '( ':   i   =   4;break;
  case   ') ':   i   =   5;break;
  case   '# ':   i   =   6;break;
  default:   exit(ERROR);
        };
        switch(opnd2){
  case   '+ ':   j   =   0;break;
  case   '- ':   j   =   1;break;
  case   '* ':   j   =   2;break;
  case   '/ ':   j   =   3;break;
  case   '( ':   j   =   4;break;
  case   ') ':   j   =   5;break;
  case   '# ':   j   =   6;break;
  default:   exit(ERROR);
        };
        return   guanxi[i][j];
}

int   Operate(int   opnd1,   SElemType   theta,   int   opnd2){     /*运算     */
      int   c;
      switch(theta)
      {
          case '+ ':c   =   opnd1   +   opnd2;
                          break;
          case '- ':c   =   opnd1   -   opnd2;
                          break;
          case '* ':c   =   opnd1   *   opnd2;
                          break;
          case '/ ':c   =   opnd1   /   opnd2;
      }
      return   c;
}


char   *zhuanhuan(){                   /*中序表达式转换为后序表达式     */


        SqStack   OPTR;
        SElemType   a,   b,   c,   x,   theta;
        char   exp[30];
        int   i   =   0;
        InitStack(&OPTR);
        Push(&OPTR,   '# ');
        c   =   getchar();
        while   (c   !=   '# '   ||   GetTop(OPTR)   !=   '# '){
                if   (!In(c)){
                        exp[i]   =   c;
        i++;
                        c   =   getchar();
                }
                else
                        switch(Precede(GetTop(OPTR),c)){
                                case   ' < ':   Push(&OPTR,   c);
    c   =   getchar();
    break;
                                case   '> ':   if(c   ==   ') '){
            while   (GetTop(OPTR)   !=   '( '   ){
    Pop   (&OPTR,   &a);
    exp[i]   =   a;
    i++;
            }
            Pop(&OPTR,   &x);
            c   =   getchar();
    }
    else{
            Pop(&OPTR,   &b);
            exp[i]   =   b;
            i++;
    }
    break;
            }
        }
        exp[i]   =   '\0 ';
        printf( "%s\n ",exp);
        return   exp;
}

char   qiuzhi(char   *exp){                 /*后序表达式求值       */
        SqStack   OPND;
        int   i   =   0;
        SElemType   a,   b;
        int   j;
        SElemType   c   =   exp[i];
        InitStack(&OPND);
        while(c){
if(!In(c)){
        Push(&OPND,   c   -   '0 ');
        c   =   exp[++i];
}
else{
        Pop(&OPND,   &a);
        Pop(&OPND,   &b);
        j   =   Operate(b,   c,   a);
        Push(&OPND,   j);


        c   =   exp[++i];
}
        }
        return   GetTop(OPND);
}

void   main(){                 /*主程序     */
    char   *ch   =   zhuanhuan();
    char   i;
    i   =   qiuzhi(ch);
    printf( "%d\n ",   i);
}

[解决办法]
数据结构辅导:
http://sysop.com.cn/system4864,1.html

这两个连接中讲述的都是楼主你所做的工作,
【推荐这个连接http://sysop.com.cn/system4864,1.html】
看看这个思想、算法,以及参看一下其中的代码吧 ~~
[解决办法]
zhuanhuan()函数中,exp为局部变量,生存期为函数期限,调用完后当然就没有了,当然不能被返回了,你可以尝试用全局变量或引用类型
[解决办法]
多调试, 单步跟踪, 添加watch查看表达式值

呵呵 编程不仅要会编程序, 调试也是非常重要的
[解决办法]
在zhuanhuan() 函数中,exp为局部变量,该内存地址在返回主函数之后被释放掉了..

把exp的定义改为: static char exp[30]; 试试.
[解决办法]
楼主你出错的原因应该是在zhuanhuan这个函数中,你的返回值是一个栈内的变量,是一个数组名.
这是不行的,因为当这个函数结束之后,这个exp也就生命期结束了,所以返回的只是一堆无用的垃圾而已.你要把它改成在堆上建立的数组才行,另外在主函数接收之后,要记得释放内存,我改了一下,如下:

char *zhuanhuan(){ /*中序表达式转换为后序表达式 */
SqStack OPTR;
SElemType a, b, c, x, theta;

// char exp[30];
char *exp=(char*)malloc(30); //在这里改为堆内存

int i = 0;
InitStack(&OPTR);
Push(&OPTR, '# ');
c = getchar();
while (c != '# ' || GetTop(OPTR) != '# '){
if (!In(c)){
exp[i] = c;
i++;
c = getchar();
}
else
switch(Precede(GetTop(OPTR),c)){
case ' < ': Push(&OPTR, c);
c = getchar();
break;
case '> ': if(c == ') '){
while (GetTop(OPTR) != '( ' ){
Pop (&OPTR, &a);
exp[i] = a;
i++;
}
Pop(&OPTR, &x);
c = getchar();
}
else{
Pop(&OPTR, &b);
exp[i] = b;
i++;
}
break;
}
}
exp[i] = '\0 ';
printf( "%s\n ",exp);
return exp;
}


void main(){ /*主程序 */
char *ch = zhuanhuan();
char i;
i = qiuzhi(ch);
printf( "%d\n ", i);
free(ch); //这里记得free掉内存就行了
}

[解决办法]
返回函数内的局部变量(本例中的exp数组),也就是栈内存是一个很大的错误,因为栈内存的生命期是在函数内,函数结束它的生命就结束了

堆内存是可以返回的(改成exp=(char*)malloc(30)之后),因为它的生命期是程序级的,在整个程序运行期间一直存在

热点排行