C 后缀计算器不工作

C 后缀计算器不工作,c,shell,postfix-notation,C,Shell,Postfix Notation,出于某种原因,当我用下面的表达式执行这个程序时,它返回一个无效的否定答案-46。我很好奇到底出了什么问题,希望尽快解决 #include <stdio.h> #include <stdlib.h> #include "usefunc.h" #define OFFSET '0' /* * I only use one constant.....I really don't need another. and in fact took more * memory to us

出于某种原因,当我用下面的表达式执行这个程序时,它返回一个无效的否定答案
-46
。我很好奇到底出了什么问题,希望尽快解决

#include <stdio.h>
#include <stdlib.h>
#include "usefunc.h"
#define OFFSET '0'

/*
* I only use one constant.....I really don't need another. and in fact took more
* memory to use the constant than without. several bytes!!
*/

/*

* for this program, I found a library that contained C implementations
* of a stack. I thought I'd use it, since I understand everything it
* does fully. you can quiz me on the stuff I did not write, if you want.

*/

//setting up the stack
typedef char stackElementT;

//it's a struct, so it can contain several elements
//like maxSize, top, and of course the contents
//let's call it stackT
typedef struct {
  stackElementT *contents;
  int maxSize;
  int top;
  int min2;
} stackT;

//allocates the memory for the size passed to the function
//then checks if there's enough memory
//then sets the size to maxSize, `top` to -1 (empty), and contents to newContents
void StackInit(stackT *stackP, int maxSize) {
    stackElementT *newContents;
    newContents = (stackElementT *)malloc(sizeof(stackElementT)*maxSize);
    if (newContents == NULL) {
        fprintf(stderr, "Not enough memory.\n");
        exit(1);
    }

    stackP->contents = newContents;
    stackP->maxSize = maxSize;
    stackP->top = -1; //empty...
}

//frees the allocated memory
//sets it all to NULL
//sets the size to 0, all that good stuff
void StackDestroy(stackT *stackP) {
    free(stackP->contents);
    stackP->contents = NULL;
    stackP->maxSize = 0;
    stackP->top = -1; //empty
}

//just referencing top
int StackIsEmpty(stackT *stackP) {
    return stackP->top < 0;
}

//and top again
int StackIsFull(stackT *stackP) {
    return stackP->top >= stackP->maxSize-1;
}

//and top once more
//adds one to the top of the stack by first incrementing the top, and then adding the element in at the top
//unless of course it's full
void StackPush(stackT *stackP, stackElementT element) {
    if(StackIsFull(stackP)) {
        fprintf(stderr, "Can't push element: stack is full.\n");
        exit(1);
    }
    stackP->contents[++stackP->top] = element;
}
//pops it, and then subsequently updates `top`
//unless of course it's empty
stackElementT StackPop(stackT *stackP) {
    if(StackIsEmpty(stackP)) {
        fprintf(stderr, "Can't pop element: stack is empty.\n");
        exit(1);
    }
    return stackP->contents[stackP->top--];
}

/*

* my work starts here:

*/

double eval(double x, double y, char operand) {
    switch(operand) {
        case '+': return x+y;
        case '-': return x-y;
        case '/': return x/y;
        case '*': return x*y;
        case '^': return pow(x, y);
    }
}

int is_operand(char x) {
    switch(x) {
        case '+':
        case '-':
        case '/':
        case '*':
        case '^': return 1;
        default: return 0;
    }
}

double postfix(char* expr, int length) {
    //counter, and two temporary variables
    int i;
    double temp = 0, temp2;
    //and of course the stack
    stackT stack;
    //lotta frames...
    StackInit(&stack, 1000);
    //loops through string input. as of now, it only works with one digit numbers :(
    for (i = 0; i < length; i++) {
        //printf("%d : %c\n", expr[i], expr[i]);
        //is it a number? yes? push the decimal version of it to the stack
        if ((expr[i] >= '0') && (expr[i] <= '9')) {
            //printf("temp=%f\n", temp);
            temp *= 10;
            temp += expr[i]-OFFSET;
            //printf("temp=%f\n", temp);
        }
        else if (expr[i] == ' ') {
            StackPush(&stack, temp);
            temp = 0;
        }

        //no?
        else {
            //switch-case statement, easy peasy
            switch (expr[i]) {
                //operations checking
                case '+': {
                    temp = StackPop(&stack);
                    temp2 = StackPop(&stack);
                    //printf("%f+%f\n", temp2, temp);
                    StackPush(&stack, temp2+temp);
                    temp = temp2+temp;
                }
                    break;
                case '-': {
                    temp = StackPop(&stack);
                    temp2 = StackPop(&stack);
                    //printf("%f-%f\n", temp2, temp);
                    StackPush(&stack, temp2-temp);
                    temp = temp2-temp;
                }
                    break;
                case '/': {
                    temp = StackPop(&stack);
                    temp2 = StackPop(&stack);
                    //printf("%f/%f\n", temp2, temp);
                    StackPush(&stack, temp2/temp);
                    temp = temp2/temp;
                }
                    break;
                case '*': {
                    temp = StackPop(&stack);
                    temp2 = StackPop(&stack);
                    //printf("%f*%f\n", temp2, temp);
                    StackPush(&stack, temp2*temp);
                    temp = temp2*temp;
                }
                    break;
                //POWERS?!?! whoa. this wasn't required.
                case '^': {
                    temp = StackPop(&stack);
                    temp2 = StackPop(&stack);
                    //printf("%f^%f\n", temp2, temp);
                    StackPush(&stack, pow(temp2, temp));
                    temp = pow(temp2, temp);
                }
                default:
                    break;
            }
        }
    }
    //just giving the number it pushed
    return StackPop(&stack);
}

int main() {
    //so many counters...!
    //almost a shell
    while (1) {
        //prompt
        printf("postfix expression:\t");
        //getLine
        char *expr = GetLine();
        //aaaaaaaaaand evaluate it
        printf("%.0f\n\n", postfix(expr, strlen(expr)));
    }
}
#包括
#包括
#包括“usefunc.h”
#定义偏移量“0”
/*
*我只使用一个常数……我真的不需要另一个。事实上花了更多的时间
*内存使用常数比不使用常数。几个字节!!
*/
/*
*对于这个程序,我发现了一个包含C实现的库
*一叠。我想我会用它,因为我了解它的一切
*完全没有。如果你愿意的话,你可以就我没有写的东西对我进行测验。
*/
//设置堆栈
typedef char stackElementT;
//它是一个结构,因此可以包含多个元素
//比如maxSize,top,当然还有内容
//我们叫它斯塔克特
类型定义结构{
stackElementT*内容;
int-maxSize;
int top;
int min2;
}斯塔克特;
//为传递给函数的大小分配内存
//然后检查内存是否足够
//然后将大小设置为maxSize,`top`设置为-1(空),将内容设置为newContents
void StackInit(stackT*stackP,int maxSize){
stackElementT*新内容;
newContents=(stackElementT*)malloc(sizeof(stackElementT)*maxSize);
if(newContents==NULL){
fprintf(stderr,“内存不足。\n”);
出口(1);
}
stackP->contents=newContents;
stackP->maxSize=maxSize;
stackP->top=-1;//为空。。。
}
//释放分配的内存
//将其全部设置为空
//将大小设置为0,所有这些都很好
无效堆栈销毁(stackT*stackP){
免费(stackP->contents);
stackP->contents=NULL;
stackP->maxSize=0;
stackP->top=-1;//为空
}
//只是参考顶部
int StackIsEmpty(stackT*stackP){
返回stackP->top<0;
}
//再上一层
int StackIsFull(stackT*stackP){
返回stackP->top>=stackP->maxSize-1;
}
//再上一次
//通过先增加顶部,然后在顶部添加元素,将一个元素添加到堆栈顶部
//当然,除非已经满了
无效StackPush(stackT*stackP,stackElementT元素){
如果(StackIsFull(stackP)){
fprintf(stderr,“无法推送元素:堆栈已满。\n”);
出口(1);
}
stackP->contents[++stackP->top]=元素;
}
//弹出它,然后随后更新'top'`
//当然,除非它是空的
stackElementT StackPop(stackT*stackP){
if(StackIsEmpty(stackP)){
fprintf(stderr,“无法弹出元素:堆栈为空。\n”);
出口(1);
}
返回stackP->contents[stackP->top--];
}
/*
*我的工作从这里开始:
*/
双值(双x,双y,字符操作数){
开关(操作数){
大小写“+”:返回x+y;
案例'-':返回x-y;
案例“/”:返回x/y;
大小写“*”:返回x*y;
案例“^”:返回功率(x,y);
}
}
int是_操作数(字符x){
开关(x){
格“+”:
案例'-':
案例“/”:
案例“*”:
案例“^”:返回1;
默认值:返回0;
}
}
双后缀(char*expr,int-length){
//计数器和两个临时变量
int i;
双温度=0,温度2;
//当然还有那堆
斯塔克特栈;
//洛塔框架。。。
StackInit(&stack,1000);
//循环字符串输入。到目前为止,它仅适用于一位数:(
对于(i=0;i如果((expr[i]>='0')&&(expr[i]),则问题在于堆栈元素是在平台上看似有符号的字符,而您正在围绕SCHAR_MAX进行包装


(12*12)+66=210.210十六进制,为了清楚起见,是0xd2。然而,将0xd2解释为两个补码有符号字符值会得到-46。

这不是重复的;他问了一个新问题,关于同一代码中新发现的问题。非常感谢!为什么人们看不到这一点?尽管这并不重要,但代表丢失了…我修复了它几分钟前。我们收到了相当多的案例,人们反复问同一个问题,通常伴随着大量基本相似的代码。如果你要发布一个密切相关的问题,最好(1)说这是一个相关的问题,并链接到前面的实例(2)说明你已经超越了原来的问题,并且再次陷入困境,(3)明确说明新问题的不同之处。这都是提出好问题的艺术的一部分。