vasua99 Дата: Воскресенье, 02 Февраля 2014, 11:29 | Сообщение # 1
GNU follower
Сейчас нет на сайте
Не как не могу найти где баг. Собственно программа - калькулятор, считающий выражение в обратной польской записи. Баг вот в чем - Ввожу выражение "10 20 30 +" выдает 60. Вроде где-то рядом, но не как не могу докопаться) Сам код: Pastebin
Код
/* rpn.c - implementation reverse polish notation */ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <stdbool.h> #include <errno.h> #define STACK_DEPTH 16 // operations #define ADD 0 #define SUB 1 #define MUL 2 #define DIV 3 // *ups*) #define UNDEF_V -1 // undefined value #define STACK_OF -2 // stack overflow #define STACK_NEO -3 // not enough operands in stack void print_help(); double calculate(char *expr); double gettok(char **expr); void o_add(double *st, int *top); void o_sub(double *st, int *top); void o_mul(double *st, int *top); void o_div(double *st, int *top); void (*operations[])(double *st, int *top) = { o_add, o_sub, o_mul, o_div }; bool is_end_expr = false; bool is_value; // for calculate(). if true, // then gettok() return value, otherwise operation int main(int argc, char **argv) { if (argc >= 3 || argc == 1) { print_help(); return 0; } double res = calculate(argv[1]); if (errno == UNDEF_V) { printf("ERROR: Undefined value!\n"); return UNDEF_V; } else if (errno == STACK_NEO) { printf("ERROR: Not enough operands for operation\n"); return STACK_NEO; } else if (errno == STACK_OF) { printf("ERROR: Stack overflow(max %d)\n", STACK_DEPTH); return STACK_OF; } printf("Result: "); if ((int)res == res) printf("%d\n", (int)res); else printf("%.3f\n", res); return 0; } void print_help() { printf("Usage: rpn \"rpn_expression\"\n"); } double calculate(char *expr) { double stack[STACK_DEPTH]; int top = -1; double tok; do { tok = gettok(&expr); if (is_value) { if (top + 1 >= STACK_DEPTH) { errno = STACK_OF; return -1; } stack[++top] = tok; } else { int op = tok; switch (op) { case ADD: case SUB: case MUL: case DIV: if (top + 1 < 2) { errno = STACK_NEO; return -1; } operations[op](stack, &top); break; case UNDEF_V: errno = UNDEF_V; return -1; break; } } } while (!is_end_expr); return stack[top]; } double gettok(char **expr) { char *next_tok = NULL; double res = strtod(*expr, &next_tok); /* it's bad idea, because value '0' will be considered as UNDEF_V */ if (res == 0.0) { is_value = false; switch (**expr) { case '+': res = ADD; break; case '-': res = SUB; break; case 'x': case '*': res = MUL; break; case '/': res = DIV; break; case '\0': is_end_expr = true; break; default: res = UNDEF_V; } (*expr)++; } else { is_value = true; *expr = next_tok; } // skip spaces while (isspace(**expr)) (*expr)++; return res; } void o_add(double *stack, int *top) { stack[*top - 1] += stack[*top]; (*top)--; } void o_sub(double *stack, int *top) { stack[*top - 1] -= stack[*top]; (*top)--; } void o_mul(double *stack, int *top) { stack[*top - 1] *= stack[*top]; (*top)--; } void o_div(double *stack, int *top) { stack[*top - 1] /= stack[*top]; (*top)--; }
Добавлено (02.02.2014, 11:29) --------------------------------------------- В общем нашел сам ошибку. Спасибо всем за помощь
Жизнь игра, и мы в ней пешки... А я кушаю пельмешки)
Сообщение отредактировал vasua99 - Суббота, 01 Февраля 2014, 13:52