K&R, глава 4.3. калькулятор с обратной польской нотацией. - C (СИ)
Формулировка задачи:
Добрый вечер. Я застопорился с примером из книги "C Programming Language", 2е издание. В главе 4.3 "внешние переменные" приводится код примитивного калькулятора. Переписал все, как написано в книге в один файл .с , скомпилировал в gcc, а программа при подстановке любых выражений, включая то, что приводится авторами (1 2 - 4 5 + *) выдает нули. Долго перепроверял код, но так и не могу понять, в чем причина?
Поток ввода для программы перенаправляю из текстового файла.
полдня сижу, никак к упражнениям не приступлю :-(
#include <stdio.h>
#include <stdlib.h> /* для объявления atof() */
#include <ctype.h>
#define MAXOP 100 /* максимальный размер операнда или знака */
#define NUMBER '0' /* сигнал, что обнаружено число */
#define MAXVAL 100 /* максимальная глубина стека val */
#define BUFSIZE 100
int getop(char s[]);
void push(double);
double pop(void);
/* калькулятор с обратной польской записью */
main()
{
int type;
double op2;
char s[MAXOP];
while ((type = getop(s)) != EOF) {
switch(type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero devisor\n");
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
int sp = 0; /* следующая свободная позиция в стеке */
double val[MAXVAL]; /* стек операндов */
/* push: помещает число f в стек операндов */
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error: stack full, can't push %g\n", f);
}
/* pop: извлекает и возвращает верхнее число из стека */
double pop(void)
{
if (sp > 0)
return val[--sp];
else {
printf("error: stack empty\n");
return 0.0;
}
}
int getch(void);
void ungetch(int);
char buf[BUFSIZE]; /* буфер для ungetch */
int bufp = 0; /* следующая свободная позиция в buf */
/* getop: извлекает следующий операнд или знак операции */
int getop(char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c; /* не число */
i = 0;
if (isdigit(c)) /* накопление целой части */
while (isdigit(s[i++] = c = getch()))
;
if (c == '.') /* накопление дробной части */
while (isdigit(s[i++] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
int getch(void) /* ввод символа (возможно, возвращенного в поток) */
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c) /* возвращение символа в поток ввода */
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
Ещё хотелось бы спросить, в какой среде программирования на С есть возможность отладки (но не дизассемблер)? Для ОС linuх.
Решение задачи: «K&R, глава 4.3. калькулятор с обратной польской нотацией.»
textual
Листинг программы
int main() { return 0 }