Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
0 / 0 / 1
Регистрация: 29.01.2012
Сообщений: 5

K&R, глава 4.3. калькулятор с обратной польской нотацией.

29.01.2012, 22:18. Показов 1971. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер. Я застопорился с примером из книги "C Programming Language", 2е издание. В главе 4.3 "внешние переменные" приводится код примитивного калькулятора. Переписал все, как написано в книге в один файл .с , скомпилировал в gcc, а программа при подстановке любых выражений, включая то, что приводится авторами (1 2 - 4 5 + *) выдает нули. Долго перепроверял код, но так и не могу понять, в чем причина?
Поток ввода для программы перенаправляю из текстового файла.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#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;
}
полдня сижу, никак к упражнениям не приступлю :-(

Добавлено через 6 минут
Ещё хотелось бы спросить, в какой среде программирования на С есть возможность отладки (но не дизассемблер)? Для ОС linuх.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.01.2012, 22:18
Ответы с готовыми решениями:

K&R калькулятор обратной польской записи
В известной книге есть пример калькулятора в обратной польской записи. Проблема - не помещает числа в стек. На ввод числа выдает unknown...

Калькулятор с обратной польской записью
Здравствуйте, надо написать калькулятор с обратной польской записью. в нем должны быть действия +,-,*,\ и факториал. калькулятор работает с...

Калькулятор обратной польской записи
Всем здравствуйте! Необходимо написать программу реализующую калькулятор обратной польской записи, нашел код в википедии, но он не...

4
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
29.01.2012, 22:35
В 94 единица должна i присваиваться, а не ноль. Сюдя по прототипу main это какое-то древние издание...
Цитата Сообщение от dayofstatic Посмотреть сообщение
Ещё хотелось бы спросить, в какой среде программирования на С есть возможность отладки (но не дизассемблер)? Для ОС linuх.
gdb, от среды не зависит,хотя некоторые могут с ним интегрироваться. Ну и valgrind для быстрого теста на ошибки работы с памятью.
1
0 / 0 / 1
Регистрация: 29.01.2012
Сообщений: 5
30.01.2012, 10:39  [ТС]
Цитата Сообщение от NoMasters Посмотреть сообщение
Сюдя по прототипу main это какое-то древние издание...
Ну как, книга с 90х не менялась, а так издание 2е, последнее, печать совсем свежая. Вот опечатки это плохо.
Спасибо.
0
30.01.2012, 11:35

Не по теме:

Цитата Сообщение от NoMasters Посмотреть сообщение
Судя по прототипу main это какое-то древние издание...
Авторы обращали в какой-то из глав внимание на то, что уж совсем правильно
C
1
int main() { return 0 }
но в большинстве примеров этим не заморачивались - по ANSI C 89 main() и так имеет тип int (если тип не указан), ну и ноль как-то сам собой возвращается :)

0
0 / 0 / 1
Регистрация: 29.01.2012
Сообщений: 5
30.01.2012, 12:06  [ТС]
В 96 и 99 префиксное инкриментирование было, нет опечатки, просто я невнимательный
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.01.2012, 12:06
Помогаю со студенческими работами здесь

Калькулятор на основе обратной польской нотации
Доброго времени суток! Делаю калькулятор на основе обратной польской нотации. Когда нажимаю на кнопки операций (+, -, *, /,()) выдает...

Калькулятор на основе обратной польской записи
Преподаватель задал создать калькулятор на основе обратной польской записи, а я в Java совсем новичок. Калькулятор должен содержать...

Сложный калькулятор на обратной польской (импиративная парадигма)
Доброго времени суток! Задание, написать сложный калькулятор не используя ООП Сделал на основе своего &quot;стека&quot;, все методы...

Калькулятор с использованием обратной польской записи и стеков
Необходимо написать калькулятор используя обратную польскую запись и стеки. Программа должна обрабатывать выражения, содержащие...

Калькулятор обратной польской записи. Передача данных в функцию
Добрый день. Задача написания калькулятора командной строки на основе обратной польской записи. Если подробнее, то: 1. нужно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru