Форум программистов, компьютерный форум CyberForum.ru

Возвращение в начало программы из функции - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Создание игр в текстовом режиме http://www.cyberforum.ru/cpp-beginners/thread1098408.html
Привет всем! Тут занялся написанием игрушек в текстовом режиме, типа змейки, тетриса и т.п. Суть в том, что я хочу как можно более правильно написать код, со стороны рефакторинга, со стороны выделения и освобождения памяти, и многих других аспектов. Думаю эта тема поможет многим новичкам, в написание чего-либо подобного, поэтому буду потихоньку выкладывать свои исходники и ждать ваших...
C++ Подскажите библиотеку GUI, реализующую графический интерфейс Доброй ночи. Подскажите, пожалуйста, лёгкую и простую библиотеку реализующую графический интерфейс. Сам интерфейс примитивен - пара кнопок и диалоговых окон. Это всё, что мне нужно от библиотеки. ОС - Windows, компилятор - VC++. Спасибо. http://www.cyberforum.ru/cpp-beginners/thread1098407.html
C++ Выведение на экран фигуры, которая изображает множество точек, которые удовлетворяют неравенству
Исправьте, пожалуйста, ошибки. Задача. Выведение на экран фигуры, которая изображает множество точек, которые удовлетворяют неравенство: x^2+y^2<=2(abs(x)+abs(y)) #include <math.h> #include <bios.h> int x0, y0; void main() int x, y; int gdriver - DETECT, gmode, errorcode; initgraph (&gdriver, &gmode, "g:\\bc31\\bg1");
C++ Как разрешить ввод только чисел типа int?
Доброго времени суток. Подскажите, пожалуйста, как разрешить ввод только чисел типа int. Преподаватель очень любит заваливать на этом, введя например букву, там где нужно число. Очень важно, чтобы код был негромоздким. #include <iostream> #include <cstdio> #include <conio.h> using namespace std; int roman (int,int,char); int main()
C++ Некорректно работает вывод вещественных чисел в массиве http://www.cyberforum.ru/cpp-beginners/thread1098403.html
#include "stdafx.h" #include <conio.h> #include <stdio.h> void ReadArray(double a)
C++ Вывести информацию в виде таблицы помогите, после введения данных , в конце программами должна выводится инф. в виде таблицы #include <stdio.h> #include <iostream> #include <stdlib.h> #include <time.h> #include <conio.h> #include <locale.h> using namespace std; int main (){ подробнее

Показать сообщение отдельно
kiborgdelto
71 / 73 / 27
Регистрация: 23.03.2011
Сообщений: 141
17.02.2014, 15:44  [ТС]
Цитата Сообщение от MrGluck Посмотреть сообщение
не, ну вы поняли. Советую избавиться от неочевидных magic number, иначе понять ваш замысел будет невозможно.
магические цифры это коды символов, в данном случае коды математических операций, если преобразовать их к виду 1,2,3,4,5,6,7 то придётся вводить ещё один массив и цикл на поиск того какую операцию выполнять в следствии того, что в массиве m_prioretet_oper операции расположены исходя из их приоритета, при разных значениях приоритета этот массив будет меняться

Цитата Сообщение от alsav22 Посмотреть сообщение
Не видно, где вызов самой vichis_oper() находится.
вызов происходит в многоточии, для чего нужно место вызова если нужно перейти в другую функцию?
Цитата Сообщение от MrGluck Посмотреть сообщение
Если вам нужно постоянно повторять одну и ту же операцию пока пользователь не введет нет либо просто постоянно - используйте циклы.
нужно возвращаться в начало в случае возникновения ошибки

Вообще говоря мне было нужно написать программу для вычисления заданного математического выражения с любыми допустимыми действительными значениями переменных при заданном приоритете операций (приоритет вводим с клавиатуры). Программа также должна проводить грамматический, лексический и синтаксический анализ указанного выражения, и в случае ошибки вывести сообщение с описанием произошедшей ошибки и вернуться к началу программы в место где можно эту ошибку исправить (ввести заново математическое выражение, изменить приоритет операций, ввести другие значения переменных, учитывая что если возвращаемся к вводу выражения то после этого должны ввести переменные и приоритеты, если к переменным то после них нужно ввести приоритеты). В функции main должен быть только вызов остальных функций.


на всякий случай прилагю полный код программы (она работает, но требуют доделать проблему с возвращением)
C++ (Qt)
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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
# include <cmath>
# include <limits>
# define N 100 // максимальная длина выражения которое нужно вычислить
# define N1 26 // максимальное количество переменных которые используются (=26 т.к. в латинском алфавите 26 букы)
using namespace std;
ofstream ff("res.txt");
 
char m_func[N]="a*(b-c+d)/e^s\0";
char m_perem[N1];
char m_oper[N];
double m_znach_perem[N1];
char m_prioretet_oper[N1]="()^*/+-";
double chisl_viragjenie[N];
double oper_viragjeniya[N];
const double infinity = std::numeric_limits<double>::infinity();
 
void korrektnost_virajgeniya();
void vvod();
void analisator();
double vichis_oper(int n,double a,double b);
double vichislitel();
int max_prioretet_v_skobke(int k,int s);
void perezapis_perem(int k);
void perezapis_oper(int k);
int max_prioretet();
bool chetnost(double b);
 
 
void main()
{
    double res;
    setlocale(LC_ALL, "Russian");
    vvod();
    analisator();
    res=vichislitel();
    cout<<"Полученный результат: "<<res<<endl;
    ff<<"Полученный результат: "<<res<<endl;
    system("pause");
}
 
void vvod()
{
    for(int ii=0;ii<N1;ii++) 
    {
        m_znach_perem[ii]=infinity;// заполняем массив бесконечностями, при повторной встрече переменной в выражении не запрашивать ввод значения переменной (оно уже введено ранее)
        oper_viragjeniya[ii]=infinity;
        chisl_viragjenie[ii]=infinity;
    }
 
    int variant_vvoda;
    cout<<"Выберите метод ввода математического выражения\n1. Считываение из файла\n2. Ввод с клавиатуры\n3. Использовать вариант по умолчанию (прописанный в коде программы)"<<endl;
    cin>>variant_vvoda;
    if(variant_vvoda==1||variant_vvoda==2)
    {
        for (int ii=0;m_func[ii]!='\0';ii++) m_func[ii]='\0';// удаление варианта по умолчанию для последующей записи задания
 
        if(variant_vvoda==1)// считывание из файла
        {
            ifstream f1("zadanie.txt");
            f1.getline(&m_func[0],1100);
            printf("%s\n",&m_func);
        }
        else // ввод c клавиатуры
        {
            cout<<"Введите математическое выражение"<<endl;
            cin.ignore(1);// удаление из потока данных символа перевода строки \n
            cin.getline(&m_func[0],1100 );
        }
    }
    else printf("%s\n",&m_func);
    
    korrektnost_virajgeniya();
 
    int i=0;// определяем все переменные и вводим их значения
    do
    {
        int k;
        k=(int)(m_func[i]);// определяем код символа
        if(k>=97&&k<=122) //проверяем принадлежит ли текущий символ латинскому прописному алфавиту? 97 код символа a, 122 код символа z
        {
            if (m_znach_perem[k-97]==infinity) // если переменная невстречалась то записываем её значение в соответствующий элемент массива значений переменных 
                //(значение переменной a лежит в 0-м элементе массива, z в 25)
            {
                cout<<"Введите значение переменной "<<m_func[i]<<":\n";
                cin>>m_znach_perem[k-97];
            }
        }
        i++;
    }
    while(m_func[i]!='\0');// проверяем достигли ли мы конца выражения
    
    i=2;
    char temp_prioritet[N1]="\0";
    do
    {
        int s;
        cout<<"Введите приоритет операции "<<m_prioretet_oper[i]<<":\n";
        cin>>s;
        if(s<2||s>6) 
        {
            cout<<"Некорректный приоритет\n";
            system("pause");
            exit(0);
        }
        if(temp_prioritet[s]!='\0')
        {
            cout<<"Операция с таким приоритетом уже существует\n";
            system("pause");
            exit(0);
        }
        else temp_prioritet[s]=m_prioretet_oper[i];
        i++;
    }
    while(m_prioretet_oper[i]!='\0');// проверяем достигли ли мы конца выражения
    
    i=2;
    do
    {
        m_prioretet_oper[i]=temp_prioritet[i];  
        i++;
    }
    while(temp_prioritet[i]!='\0');// проверяем достигли ли мы конца выражения
}
 
void korrektnost_virajgeniya()// проверяем корректность выражения на уровне переменных, т.е. неучитываем значения переменных
{
int i=0,s=0;// s счётчик количества скобок
bool p1=false;// используем для проверки повторяемости переменных и операций (за переменной должна всегда идти операция), true переменная, false операция
bool p2=false;      
do
{
    int k;
    k=(int)(m_func[i]);// определяем код символа
    
    if(k==40)s++;// если текущий символ открывающая скобка то увеличиваем s
    else if(k==41)
        {
            s--;// если текущий символ закрывающая скобка то уменьшаем s
            if(s<0) 
            {
                cout<<"закрывающая скобка ничего не закрывает"<<endl;
                system("pause");
                exit(0);
            }
        }
        
        else if(k<40||k>47&&k<94||k>94&&k<97||k>122) //проверяем принадлежит ли текущий символ переменной или операцией
        {
            cout<<"Некорректный символ номер "<<i<<endl;
            system("pause");
            exit(0);
        }
        else
        {
        
            if(i==0) //проверяем чтобы вырожение начиналось либо со скобки либо с переменной
                if(k>=97&&k<=122) p1=true;
                else 
                {
                    cout<<"Некорректная запись: первый символ операция отличная от ( и )\n";
                    system("pause");
                    exit(0);
                }
            else// проверяем чередование операций с переменными (переменная должна быть окружена операциями слева и справа, для операций аналогично)
            {
                if(k>=97&&k<=122) p2=true;
                else p2=false;          
                if(p1==p2)
                {
                    cout<<"Некорректная запись: ";
                    if(p1) cout<<"две подряд идущие переменные\n";
                    else cout<<"две подряд идущие операции\n";
                    system("pause");
                    exit(0);
                }
                p1=p2;
            }
        }
    i++;
    if(m_func[i]=='\0')// проверяем чтобы выражение не оканчивалось на операцию
    {
        if(p1==false)
        {
            cout<<"Последний символ операция которая ничего не делает\n";
            system("pause");
            exit(0);
        }
    }
}
    while(m_func[i]!='\0');// проверяем достигли ли мы конца выражения
    if(s!=0)
        {
            cout<<"Нехватает закрывающих скобок\n";
            system("pause");
            exit(0);
        }
}
 
void analisator()// записываем выражение в удобной форме для вычислений
{
int i=0,s1=0,s2=0;
do
{
    int k;
    k=(int)(m_func[i]);// определяем код символа
    if(k>=97&&k<=122) //проверяем является ли текущий символ  переменной
    {
        chisl_viragjenie[s1]=m_znach_perem[k-97];
        s1++;
    }
    else 
    {
        for(int ii=0;m_prioretet_oper[ii]!='\0';ii++)
        {
            if((char)(k)==m_prioretet_oper[ii])
            {
                oper_viragjeniya[s2]=ii;
                break;
            }
        }
        s2++;
    }
    i++;
}
while(m_func[i]!='\0');// проверяем достигли ли мы конца выражения
}
 
double vichis_oper(int n,double a,double b)
{
    int k;
    k=(int)(m_prioretet_oper[n]);
    switch(k)
    {
        case 42:
            return a*b;
        case 43:
            return a+b;
        case 45:
            return a-b;
        case 47:
            if(b==0)
            {
                cout<<"Ошибка. Деление на ноль"<<endl;
                system("pause");
                exit(0);
            }
            if(abs(a/b)==infinity)
            {
                cout<<"Ошибка. Выход за пределы области допустимцых для заданног типа значений, в следствии операции "<<m_prioretet_oper[n]<<endl;
                system("pause");
                exit(0);
            }
            return a/b;
        case 94:
            if(a<0)
            {
                bool b1; 
                b1=chetnost(b);
                if(b1==true)
                {
                    cout<<"Ошибка. Извлечение корня нечётной степени из отрицательного числа"<<endl;
                    system("pause");
                    exit(0);
                }
            }
            if(abs(pow(a,b))==infinity)
            {
                cout<<"Ошибка. Выход за пределы области допустимцых для заданног типа значений, в следствии операции "<<m_prioretet_oper[n]<<endl;
                system("pause");
                exit(0);
            }
            return pow(a,b);
        default:
            cout<<"Непонятная операция"<<endl;
            system("pause");
            exit(0);
    }
}
 
double vichislitel()
{
int i=0,s1=0,s2=0,s=0,skobki=0;// предпологаем что скобок нет (проверяем наличие скобок и если есть ищем сначала открывающую скобку а затем закрывающую эту скобку), s количество незакрытых скобок
do// вычисление выражений в скобках и последующее избавление от скобок
{
    if(oper_viragjeniya[i]==0)  
    {
        s1=i;
        s++;
        skobki++;
    }
    if(s!=0) if(oper_viragjeniya[i]==1)     
            {
                s2=i;
                s--;
                
                int k3;
                for(int ii=s1+1;ii<s2;)
                {
                k3=max_prioretet_v_skobke(s1,s2)-skobki;
                chisl_viragjenie[k3]=vichis_oper(oper_viragjeniya[k3+skobki],chisl_viragjenie[k3],chisl_viragjenie[k3+1]);
                perezapis_perem(k3+skobki);
                perezapis_oper(k3+skobki);
                s2--;
                }
                if(s2-s1==1)
                {
                    perezapis_oper(s1);
                    perezapis_oper(s1);
                    skobki--;
                }
                i=-1;
            }
    i++;
}
while(oper_viragjeniya[i]!=infinity);// проверяем достигли ли мы конца выражения
 
int k3;
do// вычисление выражений в скобках и последующее избавление от скобок
{
    k3=max_prioretet();
    chisl_viragjenie[k3]=vichis_oper(oper_viragjeniya[k3],chisl_viragjenie[k3],chisl_viragjenie[k3+1]);
    perezapis_perem(k3+1);
    perezapis_oper(k3);
}
while(oper_viragjeniya[0]!=infinity);// проверяем достигли ли мы конца выражения
return chisl_viragjenie[0];
}
 
int max_prioretet_v_skobke(int k,int s)
{
    int k1=oper_viragjeniya[k+1],k2=k+1;
    for(int i=k+2;i<s;i++)
    {
        if (k1>oper_viragjeniya[i]) 
        {
            k1=oper_viragjeniya[i];
            k2=i;
        }
    }
    return k2;
}
 
int max_prioretet()
{
    int k1=oper_viragjeniya[0],i=0,k2=0;
    do
    {
        if (k1>oper_viragjeniya[i]) 
        {
            k1=oper_viragjeniya[i];
            k2=i;
        }
        i++;
    }
    while(oper_viragjeniya[i]!=infinity);
    return k2;
}
 
void perezapis_perem(int k)
{
    int i=k;
do
{
    chisl_viragjenie[i]=chisl_viragjenie[i+1];
    i++;
}
while(chisl_viragjenie[i-1]!=infinity);// проверяем достигли ли мы конца выражения
}
 
void perezapis_oper(int k)
{
    int i=k;
do
{
    oper_viragjeniya[i]=oper_viragjeniya[i+1];
    i++;
}
while(oper_viragjeniya[i-1]!=infinity);// проверяем достигли ли мы конца выражения
}
 
bool chetnost(double b)
{
    double s;
    s=abs(b);
    while((s-(int)s)!=0)
    {
        s*=10;
    }
    if(s/2.==(int)s/2) return true;
    else return false;
}
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru