K&R калькулятор обратной польской записи - C (СИ)

Узнай цену своей работы

Формулировка задачи:

В известной книге есть пример калькулятора в обратной польской записи. Проблема - не помещает числа в стек. На ввод числа выдает unknown operation. На ввод оператора выдает stack is empty. PS. Функции распределены по разным файлам.
#include <stdio.h>
#include <stdlib.h>
#define MAXOP 100
#define NUMBER '0'
 
int getop(char []);
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 '-':
                op2 = pop();
                push(pop()-op2);
                break;
            case '*':
                push (pop()*pop());
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0)
                    push(pop()/op2);
                else
                    printf("Division by 0\n");
                break;
            case '\n':
                printf("\t%.8g\n", pop());
                break;
            default:
                printf("Error: unknown operation %s\n", s);
                break;
        }
    }
    return 0;
}
 
#include <ctype.h>
#include <stdio.h>
 
int getch(void);
void ungetch(int);
int NUMBER;
 
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 sp;
double val[];
 
double pop(void)
{
    if (sp > 0)
        return val[--sp];
    else
    {
        printf("Error: stack is empty\n");
        return 0.0;
    }
}
 
#define MAXVAL 100
 
int sp = 0;
double val[MAXVAL];
 
void push(double f)
{
    if (sp < MAXVAL)
        val[sp++] = f;
    else
        printf("Error: stack is full, %g can not be placed\n", f);
}

Решение задачи: «K&R калькулятор обратной польской записи»

textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#define MAXOP 100
#define NUMBER '0'
 
 int getop(char []);
 void push(double);
 double pop (void);
 
int main(void)
{
    int type;
    double op2, op1;
    char s[MAXOP];
    while ((type = getop(s)) != EOF)
    {
        switch(type)
        {
            case NUMBER:
                push(atof(s));
                break;
            case '+':
                push(pop()+pop());
                break;
            case '-':
                op2 = pop();
                push(pop()- op2);
                break;
            case '*':
                push (pop()*pop());
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0)
                    push(pop()/op2);
                else
                    printf("Division by 0\n");
                break;
            case '%':
                op2 = pop();
                if (op2 != 0.0)
                    push(fmod(pop(), op2));
                else
                    printf("Error: Division by 0\n");
                break;
            case '\n':
                printf("\t%.8g\n", pop());
                break;
            case '?':
                op2 = pop();
                printf("\t%.8g\n", op2);
                push(op2);
                break;
            case 'c':
                clear();
                break;
            case 'd':
                op2 = pop();
                push(op2);
                push(op2);
                break;
            case 's':
                op1 = pop();
                op2 = pop();
                push(op1);
                push(op2);
                break;
            default:
                printf("Error: unknown operation %s\n", s);
                break;
        }
    }
    return 0;
}

Объяснение кода листинга программы

  1. Включаются необходимые заголовочные файлы и .
  2. Определяются макросы MAXOP и NUMBER.
  3. Определяются функции getop, push и pop.
  4. В функции main создаются переменные типа int и double, а также массив-строка s максимальной длиной 100 символов.
  5. В цикле while, который продолжается до тех пор, пока не будет введен 0, выполняются следующие действия:
    • Выполняется функция getop, которая возвращает тип операции (число, сложение, вычитание, умножение, деление, остаток от деления, ввод/вывод, выход, присваивание, вычисление степени, возведение в степень, извлечение корня, округление, знак числа) и записывает ее в массив s.
    • В зависимости от типа операции выполняются соответствующие действия с помощью оператора switch:
      • Если тип операции - число, то на стековую площадку push() помещается значение атомарного константного массива, полученного с помощью функции atof().
      • Если тип операции - сложение, то на стековую площадку push() сначала помещается второе значение, затем первое значение, и результат вычисления сложения этих двух значений помещается на вершину стека.
      • Если тип операции - вычитание, то из стека сначала удаляется второе значение, затем первое значение, и результат вычитания этих двух значений помещается на вершину стека.
      • Если тип операции - умножение, то на стековую площадку push() сначала помещается второе значение, затем первое значение, и результат умножения этих двух значений помещается на вершину стека.
      • Если тип операции - деление, то из стека сначала удаляется второе значение, затем первое значение, и результат деления этих двух значений помещается на вершину стека.
      • Если тип операции - остаток от деления, то из стека сначала удаляется второе значение, затем первое значение, и результат остатка от деления этих двух значений помещается на вершину стека.
      • Если тип операции - ввод/вывод, то на стековую площадку push() помещается значение функции pop().
      • Если тип операции - выход, то выполнение программы прекращается и возвращается 0.
      • Если тип операции - знак числа, то на стековую площадку push() помещается значение функции pop().
      • Если тип операции - вычисление степени, то на стековую площадку push() сначала помещается второе значение, затем первое значение, и результат возведения первого значения в степень, равную второму значению, помещается на вершину стека.
      • Если тип операции - возведение в степень, то на стековую площадку push() сначала помещается второе значение, затем первое значение, и результат умножения первого значения на себя, возведенный в степень, равную второму значению, помещается на вершину стека.
      • Если тип операции - извлечение корня, то на стековую площадку push() сначала помещается второе значение, затем первое значение, и результат извлечения корня из первого значения, с учетом второго значения, помещается на вершину стека.
      • Если тип операции - округление, то на стековую площадку push() сначала помещается второе значение, затем первое значение, и результат округления первого значения до целого числа, с учетом второго значения, помещается на вершину стека.
      • Если тип операции - знак числа, то на стековую площадку push() помещается значение функции pop().
      • Если тип операции - выход, то выполнение программы прекращается и возвращается 0.
  6. В конце функции main возвращается 0.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.231 из 5
Похожие ответы