Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
3 / 3 / 1
Регистрация: 04.04.2018
Сообщений: 351

Калькулятор из книги The C++ programming language

01.11.2020, 22:25. Показов 1655. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
13. (*2) Введите в программу калькулятора из $$3.1 такие функции, как sqrt(), log() и sin(). Подсказка:
задайте предопределенные имена и вызывайте функции с помощью массива указателей на них. Не
забывайте проверять параметры, передаваемые этим функциям.
Дайте подсказку, сижу вторые сутки, не понимаю как это сделать.
Вот мой калькулятор
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#include<iostream>
#include<string.h>
 
using namespace std;
 
int no_of_errors;
double error(const char* s)
{
    cerr << "Error: " << s << '\n';
    no_of_errors++;
    return 1;
}
 
enum token_value {
    NAME, NUMBER, END,
    PLUS='+', MINUS='-', MUL='*',
    PRINT=';', ASSIGN='=', DIV='/',
    LP='(', RP=')'
};
 
token_value curr_tok; //last token from get_token()
 
double expr();
double term();
double prim();
double get_token();
 
double expr()
{
    double left = term();
    for(;;)
    {
        switch(curr_tok)
        {
        case PLUS:
            get_token();
            left += term();
            break;
        case MINUS:
            get_token();
            left -= term();
            break;
        default:
            return left;
        }
    }
    error("double expr() ???");
    return -1;
}
 
double term()
{
    double left = prim();
    for(;;)
    {
        switch(curr_tok)
        {
            case MUL:{
                get_token();
                left *= prim();
                break;
            }
            case DIV:{
                get_token();
                double d = prim();
                if(d == 0) return error("div on zero!");
                left /= d;
                break;
            }
            default:{
                return left;
            }
        }
    }
    error("double term() ???");
    return -1;
}
 
//-----------------------------------------
//-----------------------------------------
//-----------------------------------------
 
struct name {
    char* string;
    name* next;
    double value;
};
 
double number_value;
char name_string[256];
const int TBLSZ = 23;
name* table[TBLSZ];
 
 
name* look(const char*, int ins = 0);
inline name* insert(const char*);
 
double prim()
{
    switch(curr_tok)
    {
        case NUMBER:{
            get_token();
            return number_value;
        }
        case NAME:{
            if(get_token() == ASSIGN)
            {
                name* n = insert(name_string);
                get_token();
                n->value = expr();
                return n->value;
            }
            return look(name_string)->value;
        }
        case MINUS:{
            get_token();
            return -prim();
        }
        case LP:{
            get_token();
            double e = expr();
            if(curr_tok != RP) return error("need )");
            get_token();
            return e;
        }
        case END:{
            return 1;
        }
        default:{
            return error("need первичное");
        }
    }
}
 
double get_token()
{
    char ch;
    do //skip spaces
    {
        if(!cin.get(ch)) return curr_tok = END;
    }while(ch != '\n' && isspace(ch));
 
    switch(ch)
    {
    case ';': // end of string lexeme
    case '\n':
        cin >> ws;
        return curr_tok = PRINT;
    case '*':// operations
    case '/':
    case '+':
    case '-':
    case '(':
    case ')':
    case '=':
        return curr_tok = token_value(ch);
    case '1': // number lexeme
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '.':
        cin.putback(ch);
        cin >> number_value;
        return curr_tok = NUMBER;
    default:
        if(isalpha(ch))
        {
            char* p = name_string;
            *p++ = ch;
            while(cin.get() && isalnum(ch)) *p++ = ch;
            cin.putback(ch);
            *p = 0;
            return curr_tok = NAME;
        }
        error("bad lexeme");
        return curr_tok = PRINT;
    }
 
}
 
inline name* insert(const char* s)
{
    return look(s, 1);
}
 
name* look(const char* p, int ins)
{
    int hash_code = 0;
    const char* pp = p;
 
    while(*pp) hash_code = hash_code << 1 ^ *pp++;// all symbols
    // from input string p for queue add to hash_code
    // разряд в результате x^y равен 1 тогда и только тогда
    // когда эти разряды в операндах х и у различны. << - сдвиг влево
    if(hash_code < 0) hash_code = -hash_code;
    hash_code %= TBLSZ;
 
    //find name for hash code in chartable
    for(name* n = table[hash_code]; n; n = n->next)
    {
        if(strcmp(p, n->string) == 0) return n;
    }
    if(ins == 0) error("name not found");
    name* nn = new name; // new object for add new name in chartable
    nn->string = new char[strlen(p) + 1];
    strcpy(nn->string, p);
    nn->value = 1;
    nn->next = table[hash_code]; // add new name
    table[hash_code] = nn;
    return nn;
}
 
// main == driver. He init and stat proccess
int main()
{
    insert("pi")->value = 3.141592;
    insert("e")->value = 2.718281;
    while(cin)
    {
        get_token();
        if(curr_tok == END) break;
        if(curr_tok == PRINT) continue;
        cout << expr() << endl;
    }
    return 0;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.11.2020, 22:25
Ответы с готовыми решениями:

Существует ли перевод книги Страуструпа C++ programming language, 4th edition?
Всем привет Меня интересует следующий вопрос: Кто-то видел полностью переведенную книгу от Страуструпа &quot;c++ programming...

D Programming Language
Вообщем вот, что мне удалось найти для работы с языком D. Список IDE* *Ссылка на D-IDE ведет на Mono-D Правильная ссылка на...

HTML-as-programming-language
Не подскажите, для чего это используется? https://pypi.org/project/HTML-as-programming-language/

6
3 / 3 / 1
Регистрация: 04.04.2018
Сообщений: 351
02.11.2020, 11:09  [ТС]
Ребя поможет кто? Вопрос актуален. Буду рад любой помощи
0
Just Do It!
 Аватар для XLAT
4211 / 2668 / 655
Регистрация: 23.09.2014
Сообщений: 9,082
Записей в блоге: 3
02.11.2020, 11:29
Цитата Сообщение от dimmarvel Посмотреть сообщение
любой помощи
тут такая бида, если я начну править ваш код,
то этот код уже не будет котом из книги,
ну, и ясень это вас не устроит.
0
3 / 3 / 1
Регистрация: 04.04.2018
Сообщений: 351
02.11.2020, 13:16  [ТС]
XLAT, Почему не устроит? Думаю я смогу прочесть то что вы напишите в коде(Надеюсь )
0
Just Do It!
 Аватар для XLAT
4211 / 2668 / 655
Регистрация: 23.09.2014
Сообщений: 9,082
Записей в блоге: 3
02.11.2020, 14:29
Лучший ответ Сообщение было отмечено dimmarvel как решение

Решение

Цитата Сообщение от dimmarvel Посмотреть сообщение
Думаю я смогу прочесть то что вы напишите в коде
тогда держите:
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <iostream>
#include <iomanip>
#include <deque>
#include <cmath>
#include <string.h>
 
#include <windows.h>
namespace color
{   std::ostream& set(WORD text = 7, WORD background = 0)
    {   SetConsoleTextAttribute(    GetStdHandle(STD_OUTPUT_HANDLE),
                                    (background << 4) | text      );
        return std::cout;
    }
};
 
#define BANNER(v1,v2,v3) color::set(15);\
    std::cout << v1 << "\n" << v2 << "\n" << v3 << "\n"; color::set();
 
class Calculator
{   private:    
        class  smycin
        {   
        public:
            void set(const std::string& s)
            {   for(const auto& e : s)
                {   d.push_back(e);
                }
                //info();
            }
 
            void putback(char c)
            {   d.push_front(c);
            }
            
            char get()
            {   char c = d.front();
                d.pop_front();
                return c;
            }
 
        private:
            std::deque<char> d;
            void info()
            {   for(size_t i = 0; i < d.size(); i++)
                    std::cout << d[i];
                std::cout << "\n";
            }
        } my;
 
        double number()
        {   double res = 0;
            double m = 1.;
            bool  b = false;
            for (;;)
            {   char c = my.get();
                if (c >= '0' && c <= '9')
                {   res = res * 10 + c - '0';
                    if(b) m *= 10;
                }
                else if (c == '.') b = true;
                else
                {   my.putback(c);
                    return res/m;
                }
            }
        }
 
        double skobki()
        {   char c = my.get();
            if (c == '(')
            {   double x = expr();
                my.get();
                return x;
            }
            else
            {   my.putback(c);
                return number();
            }
        }
 
        double factor()
        {   double x = skobki();
            for (;;)
            {   char c = my.get();
                switch (c)
                {   case '*':
                        x *= skobki();
                        break;
                    case '/':
                        x /= skobki();
                        break;
                    default:
                        my.putback(c);
                        return x;
                }
            }
        }
 
        double expr()
        {   double x = factor();
            for (;;)
            {   char c = my.get();
                
                if(isalpha(c))//////////////////////////////////////////////////
                {   char buf[32] = {c};
                    int i;
                    for(i = 0; isalpha(c); ++i)
                    {   buf[i] = c;
                        c = my.get();
                    }
                    buf[i] = 0;
                    //std::cout << "\ntest: " << buf << "\n";
                    my.putback(c);
                    
                    if(strcmp(buf, "sin" ) == 0) return x = sin (factor());
                    if(strcmp(buf, "cos" ) == 0) return x = cos (factor());
                    if(strcmp(buf, "sqrt") == 0) return x = sqrt(factor());
                    if(strcmp(buf, "log" ) == 0) return x = log (factor());
                }
                
                switch (c)
                {   case '+':
                        x += factor();
                        break;
                    case '-':
                        x -= factor();
                        break;
                    default:
                        my.putback(c);
                        return x;
                }
            }
        }
    
    public:
        ///---------------------------------------------|
        /// Здесь есть всё!                             |
        /// Что ты должен знать об этом калькуляторе!!! |
        ///---------------------------------------------:
        double res;
        double go(std::string str)
        {   std::cout << "    Virazhenie: ";
            color::set(14); std::cout << str; color::set();
            my.set(str);
            res = expr();
            std::cout << " = " << std::setprecision(15) << res << std::endl;
            return res;
        }
};
 
Calculator calc;
bool auto_test(const char* s, double d)
{   if(calc.go(s) == d)
    {   color::set(10); std::cout << "    TEST OK!\n\n"; color::set();
        return true;
    }
    else
    {   color::set(12); std::cout << "    TEST FAIL!\a\n\n"; color::set();
        return false;
    }
}
 
///----------------------------------------------------------------------------|
/// Тест.
///----------------------------------------------------------------------------:
int main()
{   
    calc.go("0.4*(2.3+6.7)/(5.8-9.1)"); 
    std::cout << "/// Otvet: -1.09090909090909\n\n";
    
    BANNER(
    "|-----------------------------------------------------|",
    "|                 auto_test is work!                  |",
    "|-----------------------------------------------------:")
    bool sucsess   = true;
         sucsess &= auto_test("2/0"                , 5                );
         sucsess &= auto_test("sin(3.14/3)"        , sin(3.14/3)      );
         sucsess &= auto_test("1+1+(cos(3.14))+1+1", 1+1+cos(3.14)+1+1);
         sucsess &= auto_test("1+(sqrt(sin(3.14/5)))+(log(5))+(cos(10))", 
                               1+(sqrt(sin(3.14/5)))+(log(5))+(cos(10)));
    
    if(sucsess) std::cout << "Common resultat: ALL GOOD!\n";
    else        std::cout << "Common resultat: IT IS BAD!\n";
 
    std::cin.get();
}


это модификация вот этой темы
Сделать калькулятор арифметического выражения
под ваше условие(добавить фанки)
2
Just Do It!
 Аватар для XLAT
4211 / 2668 / 655
Регистрация: 23.09.2014
Сообщений: 9,082
Записей в блоге: 3
02.11.2020, 15:37
улучшенная версия:
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <iostream>
#include <iomanip>
#include <deque>
#include <cmath>
 
#include <windows.h>
namespace color
{   std::ostream& set(WORD text = 7, WORD background = 0)
    {   SetConsoleTextAttribute(    GetStdHandle(STD_OUTPUT_HANDLE),
                                    (background << 4) | text      );
        return std::cout;
    }
};
 
#define BANNER(v1,v2,v3) color::set(15);\
    std::cout << v1 << "\n" << v2 << "\n" << v3 << "\n"; color::set();
 
class Calculator
{
private:
    class  smycin
    {
    public:
        void set(const std::string& s)
        {   d.clear();
            for(const auto& e : s)
            {   d.push_back(e);
            }
            //info();
        }
 
        void putback(char c)
        {   d.push_front(c);
        }
 
        char get()
        {   char c = d.front();
            d.pop_front();
            return c;
        }
 
    private:
        std::deque<char> d;
        void info()
        {   for(size_t i = 0; i < d.size(); i++)
                std::cout << d[i];
            std::cout << "\n";
        }
    } my;
 
    double number()
    {   double res = 0;
        double m = 1.;
        bool  b = false;
        for (;;)
        {   char c = my.get();
            if (c >= '0' && c <= '9')
            {   res = res * 10 + c - '0';
                if(b) m *= 10;
            }
            else if (c == '.') b = true;
            else if(isalpha(c))/////////////////////////////////////////////////
            {   std::string buf;
                for(int i = 0; isalpha(c); ++i)
                {   buf.push_back(c);
                    c = my.get();
                }
                my.putback(c);
 
                if(buf == "sin" ) return sin (factor());
                if(buf == "cos" ) return cos (factor());
                if(buf == "sqrt") return sqrt(factor());
                if(buf == "log" ) return log (factor());
                else std::cout << "\nERROR: Token \"" << buf
                               << "\" is not exist!\"\n";
                return 0;
            }
            else
            {   my.putback(c);
                return res/m;
            }
        }
    }
 
    double skobki()
    {   char c = my.get();
        if (c == '(')
        {   double x = expr();
            my.get();
            return x;
        }
        else
        {   my.putback(c);
            return number();
        }
    }
 
    double factor()
    {   double x = skobki();
        for (;;)
        {   char c = my.get();
            switch (c)
            {   case '*':
                    x *= skobki();
                    break;
                case '/':
                    x /= skobki();
                    break;
                default:
                    my.putback(c);
                    return x;
            }
        }
    }
 
    double expr()
    {   double x = factor();
        for (;;)
        {   char c = my.get();
            switch (c)
            {   case '+':
                    x += factor();
                    break;
                case '-':
                    x -= factor();
                    break;
                default:
                    my.putback(c);
                    return x;
            }
        }
    }
 
public:
    ///---------------------------------------------|
    /// Здесь всё!                                  |
    /// Что ты должен знать об этом калькуляторе!!! |
    ///---------------------------------------------:
    double res;
    double go(std::string str)
    {   std::cout << "    Virazhenie: ";
        color::set(14);
        std::cout << str;
        color::set();
        my.set(str);
        res = expr();
        std::cout << " = " << std::setprecision(15) << res << std::endl;
        return res;
    }
};
 
Calculator calc;
bool auto_test(const char* s, double d)
{   if(calc.go(s) == d)
    {   color::set(10);
        std::cout << "    TEST OK!\n\n";
        color::set();
        return true;
    }
    else
    {   color::set(12);
        std::cout << "    TEST FAIL!\a\n\n";
        color::set();
        return false;
    }
}
 
///----------------------------------------------------------------------------|
/// Тест.
///----------------------------------------------------------------------------:
int main()
{   calc.go("0.4*(2.3+6.7)/(5.8-9.1)");
    std::cout << "/// Otvet: -1.09090909090909\n\n";
 
    BANNER(
        "|-----------------------------------------------------|",
        "|                 auto_test is work!                  |",
        "|-----------------------------------------------------:")
    bool sucsess   = true;
         sucsess &= auto_test("Trololo + 1"        , 1                );
         sucsess &= auto_test("sin(3.14/3)"        , sin(3.14/3)      );
         sucsess &= auto_test("1+1+cos(3.14)+1+1"  , 1+1+cos(3.14)+1+1);
         sucsess &= auto_test("1+1+cos(3.14)+1+1"  , 1+1+cos(3.14)+1+1);
         sucsess &= auto_test("1+sqrt(sin(3.14/5))+log(5)+cos(10)" ,
                               1+sqrt(sin(3.14/5))+log(5)+cos(10) );
 
    if(sucsess) std::cout << "Common resultat: ALL GOOD!\n" ;
    else        std::cout << "Common resultat: IT IS BAD!\n";
 
    std::cin.get();
}

блок с фанками перевоткнул туда куда надо:
теперь не надо лишних скобок.
+убрал си
1
3 / 3 / 1
Регистрация: 04.04.2018
Сообщений: 351
02.11.2020, 15:49  [ТС]
XLAT, Спасибо)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.11.2020, 15:49
Помогаю со студенческими работами здесь

Online programming language ident
Нашел кусок кода с непонятным синтаксисом, попробовал распознать принадлежность к ЯП с помощью онлайн сервиса, что еще больше запутало: ,...

L++ is a programming language with Lisp-like syntax
The L++ Programming Language, обсуждение: https://news.ycombinator.com/item?id=7711755

Русский язык в CLIPS Rule Based Programming Language
Прошу подсказать, если на самом деле проблемы нет или подключиться знающим людям к дискуссии с автором языка. Добавлено через 6 минут ...

Куда делись Code Conventions for the Java Programming Language?
Как бы за ссылкой ничего нет - посмотреть, файлы скачать нельзя: http://www.oracle.com/technetwork/java/codeconv-138413.html Где...

Raphael Finkel "Advanced Programming Language Design" на русском.
Скажите пожалуйста, кто знает, не переводилась ли книга Raphael Finkel 'Advanced Programming Language Design' на русский язык? Заранее...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru