goto в С++.
- Pika4u
- Поставщик валерьянки для Кота
- Сообщения: 2064
- Зарегистрирован: Пт апр 24, 2009 11:39:16
- Откуда: г.Оренбург
goto в С++.
Пишу программы для компьютера. На С++. Раньше ещё немного знал асм для АВР. И меня заинтересовало, есть ли в С++ метки и команды перехода по метке. Оказывается, есть. Эта команда называется goto. Но я прочитал про неё много нелестных отзывов в интернете. Ну не знаю, мне так легче меток понаставить, чем городить кучу циклов. Хотя на компиляцию программы с goto уходит дольше времени-секунд 7. Кто что думает?)
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Re: goto в С++.
Фигня, longjmp() пользуй 
Re: goto в С++.
между С и С++ очень большая разница и вам как новичку надо наплевать на предрассудки опытных программистов.Пишите как вам удобно,потом разберётесь-нужно вам "goto" или нет.
- Pika4u
- Поставщик валерьянки для Кота
- Сообщения: 2064
- Зарегистрирован: Пт апр 24, 2009 11:39:16
- Откуда: г.Оренбург
Re: goto в С++.
Satyr писал(а):Фигня, longjmp() пользуй
Сейчас попробую)) longjmp()-в скобках что писать?)) это тоже самое, что goto?)))
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
- Pika4u
- Поставщик валерьянки для Кота
- Сообщения: 2064
- Зарегистрирован: Пт апр 24, 2009 11:39:16
- Откуда: г.Оренбург
Re: goto в С++.
Прочитал в гугле про лонгджамп-не понравилось. гото проще)))
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: goto в С++.
если в программе меньше 24 меток и меньше 32 goto на них из разных мест - это не программа, а срамота. никогда так не пишите - засмеют все!
битва с дураками проиграна, победители торжествуют. слава победителям!
Re: goto в С++.
Vov123 писал(а):Пишите как вам удобно,потом разберётесь-нужно вам "goto" или нет.
+1
Нет ничего такого.
- Pika4u
- Поставщик валерьянки для Кота
- Сообщения: 2064
- Зарегистрирован: Пт апр 24, 2009 11:39:16
- Откуда: г.Оренбург
Re: goto в С++.
Мастер Ломастер писал(а):если в программе меньше 24 меток и меньше 32 goto на них из разных мест - это не программа, а срамота. никогда так не пишите - засмеют все!
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Re: goto в С++.
goto работает замечательно, но с этим оператором сложно читать код.
Дедушка Вирт доказал, что любой код можно написать на простейши логических конструкциях без гото...
В общем вердикт: если удобно гото - пользуйте, но старайтесь свести его применение к минимуму. С и С++ имеет достаточно прозрачные механизмы (например return не в конце функции, как обычно, а по условию и в любом месте где удобно; или циклы do... while) написания программ без гото. В конце концов вы сами дойдете до момента когда не захотите использовать гото.
Дедушка Вирт доказал, что любой код можно написать на простейши логических конструкциях без гото...
В общем вердикт: если удобно гото - пользуйте, но старайтесь свести его применение к минимуму. С и С++ имеет достаточно прозрачные механизмы (например return не в конце функции, как обычно, а по условию и в любом месте где удобно; или циклы do... while) написания программ без гото. В конце концов вы сами дойдете до момента когда не захотите использовать гото.
- Dr. Alex
- Это не хвост, это антенна
- Сообщения: 1438
- Зарегистрирован: Вт окт 28, 2008 09:00:18
- Откуда: Украина, Харьков
- Контактная информация:
Re: goto в С++.
Вообще-то по правилам хорошего тона, оператор GOTO неиспользуется в языках высокого уровня. Но, как говорится, если очень хочется, но нельзя, то - можно
. Главное не переусердствовать
Я для себя его не использую. Просто пишу процедурку или функцию. И всё...
Я для себя его не использую. Просто пишу процедурку или функцию. И всё...
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
- Pika4u
- Поставщик валерьянки для Кота
- Сообщения: 2064
- Зарегистрирован: Пт апр 24, 2009 11:39:16
- Откуда: г.Оренбург
Re: goto в С++.
В принципе, если сделать нормальные комментарии, то можно и не запутаться. Да и если пишешь прогу для себя, то хоть об"goto"йся))
Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Re: goto в С++.
Pika4u писал(а):В принципе, если сделать нормальные комментарии, то можно и не запутаться. Да и если пишешь прогу для себя, то хоть об"goto"йся))
Угу. Вот только когда через месяц-два захочется прогу подправить, то выяснится - легче по новой написать, чем разобраться в goto из 10 разных мест в одно с расстояния от 10 до 1000 строчек.
В Инете полно книжек о ПРАВИЛЬНЫХ приемах программирования. И правильные приемы - они потому и правильные, что экономят усилия. Лучше сразу их усвоить, чем потом переучиваться.
Мне понравилась "ВЕРЕВКА ДОСТАТОЧНОЙ ДЛИНЫ, ЧТОБЫ ВЫСТРЕЛИТЬ СЕБЕ В НОГУ.
Правила программирования на С и С++." Ален И. Голуб
Хотя с другой стороны "Обходя не наступая разложенные грабли теряешь возможность приобрести практический опыт"
Человек - это звучит гордо, а обезьяна - объективно...
Re: goto в С++.
Vov123 писал(а):между С и С++ очень большая разница и вам как новичку надо наплевать на предрассудки опытных программистов.Пишите как вам удобно,потом разберётесь-нужно вам "goto" или нет.
Да-да!! Даешь изобретение велосипеда! С квадратными колесами! потому что круглые колеса - это предрассудки опытных механиков.
Человек - это звучит гордо, а обезьяна - объективно...
Re: goto в С++.
Помню в универе я долго холиварил с одним С (не С++) кодером, который любил goto, и не верил в работу программ без него.
Все применение этого оператора в его коде сводилось к прерыванию цикла (не доходя до конца счета, или переход на следующую итерацию), и выход из функции при различных условиях (где не применим глобальный IF, например по нажатию на кнопку на неопределенной итерации бесконечного цикла (BorlandC3.11) ).
Вот так мы и холиварили, я писал break, continue и return var, а он goto lable и все тут.
Все применение этого оператора в его коде сводилось к прерыванию цикла (не доходя до конца счета, или переход на следующую итерацию), и выход из функции при различных условиях (где не применим глобальный IF, например по нажатию на кнопку на неопределенной итерации бесконечного цикла (BorlandC3.11) ).
Вот так мы и холиварили, я писал break, continue и return var, а он goto lable и все тут.
Re: goto в С++.
Errorkpi писал(а):Вот так мы и холиварили, я писал break, continue и return var, а он goto lable и все тут.
Если пишешь ты на Си
Будь хоть трижды ламер
Про такого говорят:
"Он крутой програмер"
(с) Неизвестный пасквилянт ( ПАСКвилянт от pascal, и соответственно есть и наСИльники - от С)
Отмазка - мне по большому счету пофигу, что C/C++. что Pascal/Delphi. Переключаться конечно тяжко. Но возможно.
Человек - это звучит гордо, а обезьяна - объективно...
Re: goto в С++.
О Go To и предрассудках. ИМХО, основанное на десятилетнем опыте разработки...
Наверное нет программистского или околопрограммистского форума, на котором не поднимался бы холивар о GOTO.
Одни (таких мало) говорят - "GOTO" есть хорошо, "GOTO" можно и нужно всегда использовать. Ведь так просто перейти куда надо и сделать что хочешь.
Другие, особенно читавшие много теории и мало практиковавшие - при виде "GOTO" визжат как насилуемые девственницы. Один такой писал "я не могу видеть эту мерзость. это говно. это уродство".
Но ведь - всё хорошо в меру. И всё хорошо по назначению. Гвозди молотком надо забивать, а шурупы отвёрткой вкручивать. Наоборот - плохо получается.
Итак - что хорошего в GoTo? Хорошо есть то, что можно (теоретически) перейти откуда и куда угодно. Но это в общем случае код запутывает. Ибо у каждой функции в идеале - одна точка входа и одна - выхода.
Писать вообще без GoTo можно, но иногда - это самое GoTo очень помогает сократить и УПРОСТИТЬ код на С. Например, если есть многоэтапная проверка:
Разумеется, этот код можно написать и без GoTo. Но, тогда не избежать вложенных условий или доп. переменных или того и другого.
И пусть меня утопят в нечистотах, если этот код не читаем или непонятен.
Кстати, подобыный код часто встречается при инициализации устройств.
Для себя я выработал несколько критериев использования GoTo на С.
1. Использовать GoTo можно только в пределах одной функции.
2. Если очень тянет сделать переход из одной функции внутрь другой, то значит программа плохо спроектирована и тот кто её проектировал нуждается во внушении терморектальным методом.
В общем нужно переразбить программу на функции по-другому.
3. Использовать GoTo нужно ТОЛЬКО тогда, когда это резко улучшает читабельность программы и сокращает её код.
4. НЕ использовать GoTo для организации циклов и выхода из цикла (на С есть for, while, break).
В итоге - GoTo встречается в моих программах не часто, но лишь оно уместно.
Может, всё, что я написал покажется многим очевидным, а может кому и пригодится.
Наверное нет программистского или околопрограммистского форума, на котором не поднимался бы холивар о GOTO.
Одни (таких мало) говорят - "GOTO" есть хорошо, "GOTO" можно и нужно всегда использовать. Ведь так просто перейти куда надо и сделать что хочешь.
Другие, особенно читавшие много теории и мало практиковавшие - при виде "GOTO" визжат как насилуемые девственницы. Один такой писал "я не могу видеть эту мерзость. это говно. это уродство".
Но ведь - всё хорошо в меру. И всё хорошо по назначению. Гвозди молотком надо забивать, а шурупы отвёрткой вкручивать. Наоборот - плохо получается.
Итак - что хорошего в GoTo? Хорошо есть то, что можно (теоретически) перейти откуда и куда угодно. Но это в общем случае код запутывает. Ибо у каждой функции в идеале - одна точка входа и одна - выхода.
Писать вообще без GoTo можно, но иногда - это самое GoTo очень помогает сократить и УПРОСТИТЬ код на С. Например, если есть многоэтапная проверка:
Код: Выделить всё
int f(){
// 1й этап работы
if (условие1){
init_1();
}
else goto error1;
// 2й этап работы
if (условие2){
init_2();
}
else goto error2;
// 3й этап работы
if (условие3){
init_3();
}
else goto error3;
// Всё ОК, выходим
return(0);
// Действия по завершению при ошибке на этапе 3
error3:
done_3();
// Действия по завершению при ошибке на этапе 2
error2:
done_2();
// Действия по завершению при ошибке на этапе 1
error1:
done_1();
// Ошибка, выходим
return(-1);
}
Разумеется, этот код можно написать и без GoTo. Но, тогда не избежать вложенных условий или доп. переменных или того и другого.
И пусть меня утопят в нечистотах, если этот код не читаем или непонятен.
Кстати, подобыный код часто встречается при инициализации устройств.
Для себя я выработал несколько критериев использования GoTo на С.
1. Использовать GoTo можно только в пределах одной функции.
2. Если очень тянет сделать переход из одной функции внутрь другой, то значит программа плохо спроектирована и тот кто её проектировал нуждается во внушении терморектальным методом.
3. Использовать GoTo нужно ТОЛЬКО тогда, когда это резко улучшает читабельность программы и сокращает её код.
4. НЕ использовать GoTo для организации циклов и выхода из цикла (на С есть for, while, break).
В итоге - GoTo встречается в моих программах не часто, но лишь оно уместно.
Может, всё, что я написал покажется многим очевидным, а может кому и пригодится.
Re: goto в С++.
SfS писал(а):О Go To и предрассудках. ИМХО, основанное на десятилетнем опыте разработки...
ИМХО, основанное на 30-летнем опыте разработки...
Одни (таких мало) говорят - "GOTO" есть хорошо, "GOTO" можно и нужно всегда использовать. Ведь так просто перейти куда надо и сделать что хочешь.
Другие, особенно читавшие много теории и мало практиковавшие - при виде "GOTO" визжат как насилуемые девственницы. Один такой писал "я не могу видеть эту мерзость. это говно. это уродство".
Писать вообще без GoTo можно, но иногда - это самое GoTo очень помогает сократить и УПРОСТИТЬ код на С. Например, если есть многоэтапная проверка:
В итоге - GoTo встречается в моих программах не часто, но лишь оно уместно.
Может, всё, что я написал покажется многим очевидным, а может кому и пригодится.
Кое-что покоцал - чтобы короче было...
ИМХО - пригодится начинающим однозначно! Чтобы на пустом месте войн не затевали.
Изложено вполне разумно. В общем и целом согласен. Поскольку у медиков есть фразочка: "Все - лекарство, все - яд. Разница в дозировке."
Насчет примера немного дополню
Альтернатива №1:
switch - case - и никаких доп. переменных в простейшем случае.
Альтернатива №2
Вообще-то функция инициализации возвращает код завершения (код ошибки). Т.е. идеологически правильнее
Код: Выделить всё
int f(){
// 1й этап работы
// что-то делаем, а затем
if (условие1) // условие ошибки 1
{
return ErrCode1;
}
// 2й этап работы
// что-то делаем, а затем
if (условие2) // условие ошибки 2
{
return ErrCode2;
}
...
return 0;
}
Примерно так. При этом проще отлаживать и добавлять/убирать проверки, т.е. приспосабливать к конкретному случаю.
НО! Код из примера SfS тоже имеет право на существование, поскольку ДЕЙСТВИТЕЛЬНО может оказаться лучше по части ресурсов, читаемости и т.п.
Зависит от кучи деталей. Т.е. я всего лишь изложил, как МОЖНО (но это не значит, что НУЖНО) избавиться от goto. Всего лишь альтернативное решение.
Еще раз повторю на всякий случай: все 3 варианта (goto, switch, return ErrCode) имеют право на существование. Какой лучше - зависит от задачи (и опыта программиста) .
ЗЫ: начинающим goto лучше избегать. Поскольку либо без него НУЖНО обойтись, либо задачка - не для начинающих. Остальное - крайне редко.
Человек - это звучит гордо, а обезьяна - объективно...
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: goto в С++.
В общеми и целом согласен. Так, дополнения и «вкусовые» обсуждения.
Так она-то начинала гразно ругаться, если видела много goto, но если их вообще не было, она тоже снижала балл. По мнению автора программы, парочка goto на тысячу строк кода -- нормально, если меньше, значит где-то перемудрили с вложенными if-ами, которые читать так же трудно

Хотя если хоть того, хоть другого много, значит таки надо ещё подумать над структурой.
и
Соответственно, Ваш пример перепишется так:
Какая-от из старинных программ «оценки исходников» пыталась выдать некий «коэффициент качества», базируясь на % комментариев в коде, на количестве пустых строк (просто пустая строка, разделяющая логически-связные кусочки, иногда лучше комментаряи) и т.д. Всё в том же духе «всё есть яд и всё есть лекарство, зависит от дозы».SfS писал(а):Но ведь - всё хорошо в меру. И всё хорошо по назначению. Гвозди молотком надо забивать, а шурупы отвёрткой вкручивать. Наоборот - плохо получается.
Так она-то начинала гразно ругаться, если видела много goto, но если их вообще не было, она тоже снижала балл. По мнению автора программы, парочка goto на тысячу строк кода -- нормально, если меньше, значит где-то перемудрили с вложенными if-ами, которые читать так же трудно
Во! В идеале точка выхода тоже одна. Что несколько снижает ценность советов заменить кучу goto такой же кучей точек выхода из функцииSfS писал(а):Ибо у каждой функции в идеале - одна точка входа и одна - выхода.
Хотя если хоть того, хоть другого много, значит таки надо ещё подумать над структурой.
Единственное -- на мой вкус -- лучше уход по проблеме ставить в прямой ветви if. Мне так легче читается. Сравните:SfS писал(а):Писать вообще без GoTo можно, но иногда - это самое GoTo очень помогает сократить и УПРОСТИТЬ код на С. Например, если есть многоэтапная проверка:
...
Разумеется, этот код можно написать и без GoTo. Но, тогда не избежать вложенных условий или доп. переменных или того и другого.
И пусть меня утопят в нечистотах, если этот код не читаем или непонятен.
Код: Выделить всё
if (all_ok) {
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
} else { // тут после разбора кода выше ещё надо вспомнить, от какого условия else
goto error;
}Код: Выделить всё
if (!all_ok) {
goto error;
}
// Собственно, else уже и не нужно
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
many_many_lines_of_code;
Код: Выделить всё
int f2()
{
if (!cond1()) goto error1;
init1();
if (!cond2()) goto error2;
init2();
if (!cond3()) goto error3;
init3();
return 0;
error3:
done3();
error2:
done2();
error1:
done1();
return -1;
}
Последний раз редактировалось avreal Пт сен 23, 2011 11:05:40, всего редактировалось 1 раз.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: goto в С++.
По большому счёту -- что дальше, то важнее именно читаемость. А ресурсы... Компиляторы-то всё грамотнее. Правда от этого проблемы у начинающих, компилятор ухватил суть кода («да нифига этот код полезного не делает») и выбросил всёSergeBS писал(а):НО! Код из примера SfS тоже имеет право на существование, поскольку ДЕЙСТВИТЕЛЬНО может оказаться лучше по части ресурсов, читаемости и т.п.
Перепишем обсуждаемый пример так:
Код: Выделить всё
#define BREAKABLE_BLOCK \
for( uint8_t _breakable_block_ = 1; _breakable_block_ ; _breakable_block_ = 0)
int8_t f3()
{
uint8_t level = 0;
BREAKABLE_BLOCK {
if (!cond1()) break;
init1();
++level;
if (!cond2()) break;
init2();
++level;
if (!cond3()) break;
init3();
++level;
}
switch (level) {
case 3:
return 0;
case 2: done3();
case 1: done2();
case 0: done1();
return -1;
}
}Скомпилируем avr-gcc -std=c99 -O2 -S -mmcu=atmega8 goto.c
И получим код, который совпадает с исходным вариантом из if (cond1() ) { init1(); } else { goto error1; }.
Код: Выделить всё
f3:
/* prologue: function */
/* frame size = 0 */
rcall cond1
tst r24
breq .L2
rcall init1
rcall cond2
tst r24
breq .L3
rcall init2
rcall cond3
tst r24
breq .L4
rcall init3
ldi r24,lo8(0)
ret
.L4:
rcall done3
.L3:
rcall done2
.L2:
rcall done1
ldi r24,lo8(-1)
retПри -Os код немного хуже, что-то там оптимизатор недоделал и вышло в конце такое
Код: Выделить всё
rcall init3
ldi r24,lo8(0)
ret
.L3:
rcall done2
.L2:
rcall done1
ldi r24,lo8(-1)
ret
.L4:
rcall done3
rjmp .L3Так что если пишущий хорошо сам понимает, что он делает, то и компилятор его поймёт.
+100500SergeBS писал(а):ЗЫ: начинающим goto лучше избегать. Поскольку либо без него НУЖНО обойтись, либо задачка - не для начинающих. Остальное - крайне редко.
Как было написано в одной хорошей книжке по цифровой схемотехнике (рассчитанной ещё на, обобщённо говоря, «155-тую серию»)
Сначала нужно научиться работать без «этого приёма», а со временем станет ясно, где он действительно к месту.Однако этот приём не следует рекомендоавть начинающим разработчикам, так как у них темперамент превалирует над опытом.
p.s. У меня goto мало, не в каждой программе даже. Как-то обходится в большинстве случаев.
Но и нет старания «обойтись без, бо низя».
Да, огороды в духе того BREAKABLE_BLOCK тоже не использую. Просто и так могу написать для демонстрации. И, как видите -- компилируется во вполне нормальный код
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Re: goto в С++.
avreal писал(а):#define BREAKABLE_BLOCK \
Мда....
Господин знает толк в извращениях.....
