Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
Alex_From_777
Программист по неволе
24 / 24 / 8
Регистрация: 22.04.2015
Сообщений: 472
Записей в блоге: 1
#1

О том, почему нелюбим goto; как его правильно использовать; и чем в моем случае его можно заменить?

28.09.2015, 10:47. Просмотров 669. Ответов 20
Метки нет (Все метки)

Вот есть такой оператор всеми программистами нелюбимый. Goto называется.
Говорят, что его использование всегда можно обойти и использовать что-то другое.
Но я вот не вижу, чем его в этом моем коде можно заменить? Мне надо в случае если символ не опознан предложить ввести его еще раз. (А потом может еще раз и еще раз. И еще...)
И, пользуясь случаем, где здесь у меня синтаксическая ошибка у меня. А то компилятор сообщение выдает:
[C++ Error] Unit1.cpp(37): E2448 Undefined label 'SymIn'
А я вроде по примеру делал:
https://msdn.microsoft.com/ru-ru/library/b34dt9cd.aspx

И параллельно интересно узнать, чем же так нелюбим программистами этот оператор и почему его использования следует опасаться?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
double a, b, c;
string operation, New;
cout<<"Hello world! It's console calculation.";
cout<<"\n";
cout<<"Input a= ";
cin>> a;
cout<<"Input b= ";
cin>> b;
SynIn:
cout<<"Input operation symbol  ";
cin>> operation;
if (operation!="+" && operation!="-" && operation!="*" && operation!="/")
  {cout<<"Symbol is unknown or uncorrect! Tries again!";
  goto SymIn; }
else
  if (operation=="+") c=a+b;
  if (operation=="-") c=a-b;
  if (operation=="*") c=a*b;
  if (operation=="/") c=a/b;
cout<<"a"+operation+"b= ";
cout<< c;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.09.2015, 10:47
Ответы с готовыми решениями:

как объявить правильно tr и как его использовать при вызове функции?
main.cpp case 8: cout &lt;&lt; &quot;Firs trapec # is: &quot;; cin &gt;&gt; k; k = k -...

Как правильно вызвать метод в С++ и как использовать команду goto в default
#include &lt;iostream&gt;; #include &lt;conio.h&gt;; using namespace std; void...

Объяснить (с примерами) для чего нужен RTTI, как и когда его можно и нужно использовать
доброго времени суток. вопрос такой как я понял RTTI это свойсвто языка С++...

Как можно взять один элемент двумерного массива и сравнить его с элементами его строки?
Или столбца.

Заменить каждый элемент на среднее арифметическое его и его соседей слева и справа
Помогите пожалуйста сделать лабораторную работу. Нужно объявить массив целых...

20
Velesthau
524 / 426 / 159
Регистрация: 25.11.2014
Сообщений: 1,662
28.09.2015, 11:02 #2
Цитата Сообщение от Alex_From_777 Посмотреть сообщение
Но я вот не вижу, чем его в этом моем коде можно заменить?
Самым обычным циклом.
Цитата Сообщение от Alex_From_777 Посмотреть сообщение
Мне надо в случае если символ не опознан предложить ввести его еще раз. (А потом может еще раз и еще раз. И еще...)
Сама формулировка говорит о цикличности.
Цитата Сообщение от Alex_From_777 Посмотреть сообщение
И параллельно интересно узнать, чем же так нелюбим программистами этот оператор и почему его использования следует опасаться?
Потому что при неумелом использовании, будет сложно увидеть порядок выполнения кода.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    double a, b, c=0;
    char operation;
    cout << "Hello world! It's console calculation.\nInput a= ";
    cin >> a;
    cout << "Input b= ";
    cin >> b;
    while (1)
    {
        cout << "Input operation symbol  ";
        cin >> operation;
        if (operation != '+' && operation != '-')
            cout << "Symbol is unknown or uncorrect! Tries again!";
        else break;
    }
    switch (operation)
    {
        case '+': c = a + b; break;
        case '-': c = a - b; break;
        default: cout<<"Ohh...\n";
    }
    cout << "a" << operation << "b= "<<c;
0
Игорь1986
121 / 114 / 57
Регистрация: 08.09.2014
Сообщений: 1,031
Завершенные тесты: 1
28.09.2015, 11:03 #3
Оператор Continue для циклов while в данном случае
1
Alex_From_777
Программист по неволе
24 / 24 / 8
Регистрация: 22.04.2015
Сообщений: 472
Записей в блоге: 1
28.09.2015, 11:03  [ТС] #4
Цитата Сообщение от Alex_From_777 Посмотреть сообщение
И, пользуясь случаем, где здесь у меня синтаксическая ошибка у меня. А то компилятор сообщение выдает:
Ну это просто невнимательность была и с этим разобрался я.
Но другие два вопроса так и остались на повестке дня.
0
gledor
129 / 24 / 12
Регистрация: 12.08.2015
Сообщений: 154
Завершенные тесты: 1
28.09.2015, 11:25 #5
GoTo всегда можно заменить циклами do-while, for. Перключателем switch, а так же continue и break. В твоемслучае можно использовать бесконечный цикл с условием выхода.

На деле же, мне всего лишь один раз в жизни понадобилось использовать goto. Когда я делал псевдораспараллеливание процесса рисования нескольких линий на графике, то есть заставлял их вырисовываться одновременно при помощи goto. Там действительно, по-другому никак нельзя было сделать.

А goto не то что бы не любят, сколько... опасаются. Опасаются, потому что он чрезвычайно удобен для решения в лоб. И при использовании скажем, трех таких операторов в одном месте, это скорее всего, приведет, к неработающему или косо работающему коду из-за трудностей в понятии структуры такого кода.

Добавлено через 5 минут
потому что код становится (исключительно по визуальным ощущениям) нелинейным, разобщенным, запутанным, раздробленным на части.
Поэтому циклы тут имеют бОльшее преимущество. С ними код выглядит аккуратно, логично и относительно линейно.

Так что goto опасаются исключительно из-за того, как он выглядит в коде. И не более. Ведь все циклы произошли от goto и содержат этот самый goto в своем начале. Иными словами, циклы - это красиво упакованные goto.
1
Kerry_Jr
Эксперт PHP
2210 / 2006 / 940
Регистрация: 14.05.2014
Сообщений: 5,869
Записей в блоге: 1
Завершенные тесты: 5
28.09.2015, 11:28 #6
Цитата Сообщение от Игорь1986 Посмотреть сообщение
Оператор Continue
Цитата Сообщение от gledor Посмотреть сообщение
а так же continue и break
Ну, раз уж заговорили о безусловных переходах, то и такие операторы, как continue и break в кругах гуру тоже не приветствуются, а порой даже яро осуждаются, т.к. и без них можно обойтись.
0
UltraPenguin
229 / 95 / 27
Регистрация: 20.03.2014
Сообщений: 304
Завершенные тесты: 1
28.09.2015, 11:41 #7
Я иногда когда требуется выжать максимум скорости из кода, не теряя при этом высокоуровневости (эк загнул), могу вот так пошалить:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (int i = 0; i < N; ++i)
{
   switch (Flag)
   {
      case 1:
          /*какие-то действия*/
          goto brk;
      case 2:
          /*какие-то другие действия*/
          goto brk;
      /*....*/
brk:
    }
}
С удовольствием внемлю лучшему решению, если подскажете)
1
Alex_From_777
Программист по неволе
24 / 24 / 8
Регистрация: 22.04.2015
Сообщений: 472
Записей в блоге: 1
28.09.2015, 11:47  [ТС] #8
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
т.к. и без них можно обойтись.
И что тогда использовать?

А обойтись можно практически вообще без всего. Даже без компьютера можно обойтись)))
0
gledor
129 / 24 / 12
Регистрация: 12.08.2015
Сообщений: 154
Завершенные тесты: 1
28.09.2015, 11:52 #9
Ну.. моя фантазия подсказала мне, как обойтись без continue, это еще возможно.
Но как обойтись без break в бесконечном цикле? Использовать goto?)))
Или бесконечные циклы среди гуру тоже не котируются?
1
Игорь1986
121 / 114 / 57
Регистрация: 08.09.2014
Сообщений: 1,031
Завершенные тесты: 1
28.09.2015, 11:54 #10
Kerry_Jr,

Не по теме:


Гуру это те у кого репа за штуку, а мы так подмастерья

1
UltraPenguin
229 / 95 / 27
Регистрация: 20.03.2014
Сообщений: 304
Завершенные тесты: 1
28.09.2015, 11:55 #11
Как вариант заменить while (1) на while (!stop) и когда надо выйти сделать stop = true
1
Kerry_Jr
Эксперт PHP
2210 / 2006 / 940
Регистрация: 14.05.2014
Сообщений: 5,869
Записей в блоге: 1
Завершенные тесты: 5
28.09.2015, 11:57 #12
Цитата Сообщение от Alex_From_777 Посмотреть сообщение
И что тогда использовать?
например вместо break сделать результат проверки условия ложным
C++
1
2
3
4
5
6
7
bool looping = true;
while (looping)
{
    // что-то делаем
    if (условие_выхода_из_цикла)
        looping = false;
}
вместо continue такую штуку
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// с continue
while(условие)
{
   if (условие_для_выполнения_тела_цикла_ложное) continue;
   // тело цикла
}
// без continue
while(условие)
{
    if (условие_для_выполнения_цикла_истинное)
    {
        // тело цикла
    }
}
Но это все на Ваше усмотрение. Я не говорю, что так правильно, а эдак нет.
1
gledor
129 / 24 / 12
Регистрация: 12.08.2015
Сообщений: 154
Завершенные тесты: 1
28.09.2015, 12:00 #13
Цитата Сообщение от UltraPenguin Посмотреть сообщение
Как вариант заменить while (1) на while (!stop) и когда надо выйти сделать stop = true
Ясно, значит, бесконечные циклы с отсутствием условий (while(1), for(;) не котируются...
1
UltraPenguin
229 / 95 / 27
Регистрация: 20.03.2014
Сообщений: 304
Завершенные тесты: 1
28.09.2015, 12:04 #14
gledor, скорее у всего есть своя область применения. Например, указанные безусловные бесконечные циклы успешно применяются при программировании микроконтроллеров

Добавлено через 48 секунд
Мастерство программиста ко всему прочему в правильном выборе путей и инструментов
3
gng
807 / 552 / 167
Регистрация: 08.09.2013
Сообщений: 1,495
28.09.2015, 12:17 #15
Цитата Сообщение от gledor Посмотреть сообщение
Ясно, значит, бесконечные циклы с отсутствием условий (while(1), for( не котируются...
Увы!. В конечном материальном мире нет ничего бесконечного. :-). Когда пишут while(1) подразумевают окончание цикла по break, но можно это же условие проверить и в while()... и т.п.
break и continue не котируется среди теоретиков, так как они, хоть и ни так "нагло", как goto, но всё же формально нарушают принципы структурного программирования - "в каждом блоке должен быть ровно один вход и ровно один выход".
Сам я за разнообразие :-)))
2
daslex
1291 / 535 / 177
Регистрация: 02.08.2011
Сообщений: 2,756
28.09.2015, 13:56 #16
Цитата Сообщение от UltraPenguin Посмотреть сообщение

Не по теме:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
using namespace std;
 
int main()
{
 for (int i = 0; i < N; ++i)
{
   switch (i)
   {
      case 1:
          /*какие-то действия*/
          break;
      case 2:
          /*какие-то другие действия*/
          break;
      /*....*/
     default:;
   }
}
}
}

медленнее?

Цитата Сообщение от Alex_From_777 Посмотреть сообщение
А я вроде по примеру делал:
Может лучше по этому примеру делать?
Кликните здесь для просмотра всего текста
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
#include <iostream>
 
using namespace std;
 
bool input(double &a, double &b, string &operation,   const string &operators = "+-*//" ){
 
 
    cout<<"Input a= ";
    cin>> a;
    cout<<"Input b= ";
    cin>> b;
 
    cout<<"Input operation symbol  ";
    cin>> operation;
    return operators.find(operation)!=operators.npos;
 
}
 
int main()
{
    double a, b, c;
    string operation, New;
    bool input_correct;
 
    cout<<"Hello world! It's console calculation.\n";
 
      while (!input_correct){
            input_correct = input(a,b,operation);
               switch (operation[0]){
                case '+': c=a+b; break;
                case '-': c=a-b; break;
                case '*': c=a*b; break;
                case '/': c=a/b; break;
                default:
                    cout << "Symbol \""<< operation <<"\" is unknown or uncorrect! Tries again!\n\n";
               }
      }
 
    cout<<"a"+operation+"b= ";
    cout<< c;
 
 
}


C++
1
[quote="Alex_From_777;8123317"]где здесь у меня синтаксическая ошибка у меня[/quote]
Там надо метку ставить, а-то куда идти? В неизвестность.
SynIn: ;
Цитата Сообщение от Alex_From_777 Посмотреть сообщение
чем же так нелюбим программистами этот оператор
Умелые руки его умело используют. А нелюбим потому что когда он часто повторяется в коде, из кода получается труднопроходимый лабиринт.
1
UltraPenguin
28.09.2015, 13:59
  #17

Не по теме:

Цитата Сообщение от daslex Посмотреть сообщение
медленнее?
Не медленнее, но у меня помнится были проблемы с использованием break внутри цикла, т.к. не только условие отсекалось, но и цикл завершался

0
daslex
28.09.2015, 14:01
  #18

Не по теме:

break для цикла и break для switch разные break.
В смысле по сути одно и то же, это goto, но назначения у них отличны для наших глаз.

0
UltraPenguin
28.09.2015, 14:10
  #19

Не по теме:

daslex, подождите, разве в приведенном вами примере break не выкинет из цикла? Мой код для ситуации когда есть множественное состояние переменной, но выхода из цикла не требуется.

0
daslex
28.09.2015, 14:12     О том, почему нелюбим goto; как его правильно использовать; и чем в моем случае его можно заменить?
  #20

Не по теме:

Нет конечно. С чего ему из цикла выкидывать, если он не к циклу относится.

0
28.09.2015, 14:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.09.2015, 14:12
Привет! Вот еще темы с ответами:

Заменить каждый элемент массива на среднее арифметическое его и его соседей слева и справа
При решении использовать масив в файле)

Заменить каждый элемент массива на среднее арифметическое его и его соседей слева и справа
Помогите пожалуйста. Нужно Объявить массив целых чисел и заполнить его...

Необходимо каждый элемент массива сравнить с его 8 соседями и если он больше, чем любой из элементов с которыми сравнивается, его распечатать.
Всем привет, помогите решить следующую задачу, есть массив: 3 4 5 6 7 8 9 4 2...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru