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)明确说明新问题的不同之处。这都是提出好问题的艺术的一部分。