Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
1

Выйти из нескольких функций

03.01.2014, 10:03. Показов 4105. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Необходимо при определенном условии выскочить из косвенной рекурсии. Конечно, можно сделать это монструозно, но, полагаю, есть возможность выйти изо всех эти функций безо всяких глобальных переменных и тучи if при каждом косвенном вызове на проверку этого глобального флага?
Исключения использовать нельзя.

Я бы сделал это через goto, но насколько это правильно? Разворачивает ли goto стэк? Мне кажется, что нет.. Но может я ошибаюсь?

Так бы это выглядело с goto:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void f1()
{
f2();
}
void f2()
{
if (..)
goto HERE;
f1();
}
int main()
{
f1();
HERE:
doSomethingElse();
}

Не по теме:

Пожалуйста, не надо кричать "использование goto = быдло код"..

0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.01.2014, 10:03
Ответы с готовыми решениями:

Условия для нескольких функций
Всем привет! Делаю задачку 1-го курса. Столкнулся с ошибкой: Хочу, чтобы при вводе определенного...

Работа с файлом из нескольких функций
Здравствуйте. Нужно печатать в 1 файл из нескольких функций. Предположим есть функция main void...

Возвращение из функций нескольких значений
Доброго времени суток. Нужна помощь. Дано задание: Напишите функцию swap(int& a, int& b, int& c),...

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

22
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
03.01.2014, 10:05 2
Исключение можно кинуть)
Но я даже не знаю что тут большее зло: логика на исключениях или goto.

Мысль первая: давайте жить без рекурсии.
Мысль вторая: если по каким-либо причинам нельзя, можно попробовать передавать последним аргументом какой-нибудь флаг по ссылке.
0
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
03.01.2014, 10:14  [ТС] 3
0x10,
Цитата Сообщение от nexen Посмотреть сообщение
Исключения использовать нельзя.
а прочитать сначала сообщение?

Да и так забавно, когда описываешь задачу, а тебе говорят:"изменяй условия задачи! Не используй это и это, а используй это и это" :\
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
03.01.2014, 10:18 4
Проглядел, да.

Добавлено через 3 минуты
А что касается goto - сделать-то можно, только не так просто, как в примере. Поэтому лучше не надо.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
03.01.2014, 10:32  [ТС] 5
0x10, поэтому и спрашиваю, какие есть алтернативы, может я не знаю о каком-то gotoThroughFunctions
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
03.01.2014, 10:55 6
Цитата Сообщение от nexen Посмотреть сообщение
Необходимо при определенном условии выскочить из косвенной рекурсии. Конечно, можно сделать это монструозно, но, полагаю, есть возможность выйти изо всех эти функций безо всяких глобальных переменных и тучи... Я бы сделал это через goto, но насколько это правильно? Разворачивает ли goto стэк? Мне кажется, что нет.. Но может я ошибаюсь?
Каждый экземпляр каждой функции должен завершаться, согласно логике этой функции, всё остальное - костыли. Если тебе надо во вложенном экземпляре выйти из всей рекурсии, то единственный правильный вариант - заставить все вышележащие по цепочке функции завершаться сразу же при возврате из нижележаших. Выполнилось условие, функция завершается возвращает такое (в параметре, или в значении самой функции), что вызвавшая функция её тоже завершается с аналогичным возвратом. И ни какой записи в глобальным переменные из рекурсии.
0
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
03.01.2014, 10:56  [ТС] 7
taras atavin, и будет такая туча ненужных проверок, что капец. Если функции друг из друга вызываются в -ндцати местах, то нужно добавить столько же if после них - не вариант. Вызывать функции друг из друга один раз не выйдет по упомянутой вами выше логике программы. Так же, как я говорил, не стоит писать о "каждая функция должна завершаться в соответствие её логике и это, мол, костыль", ибо по логике программы (да-да, щас начнут писать, что значит программа составлена неверно, раз такая логика) обязан быть именно такой выход, именно из косвенной рекурсии и, желательно (очень-очень), безовсяких дополнительных if. Это как добавить exit(nError) в функцию проверки на критические ошибки, вместо задания флага, что ошибка была и соответствующей проверки после функции обработки.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
03.01.2014, 10:58 8
Цитата Сообщение от nexen Посмотреть сообщение
taras atavin, и будет такая туча ненужных проверок, что капец.
Ни одной не нужной проверки не будет.

Добавлено через 1 минуту
Цитата Сообщение от nexen Посмотреть сообщение
Если функции друг из друга вызываются в -ндцати местах, то нужно добавить столько же if после них - не вариант.
Не важно, в скольких местах одна функция вызывает другую, return завершит её в любом месте.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.01.2014, 11:01 9
Реализовать f2 следующим образом:
C++
1
2
3
4
5
void f2( bool flag )
{
   if( flag ) return;
   f1();
}
1
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
03.01.2014, 11:10 10
Не будет ни одного лишнего if. Каждый экземпляр вызывает два других в двух местах, найди костыль, лишний if и монструозность:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool Search(TNode *Root, int Data, TNode *Node)
{
 bool Result;
 if (Root->Data==Data)
 {
  Node=Root;
  return true;
 }
 if (Root->Left)
 {
  Result=Search(Root->Left, Data, Node);
  if (Resutl)
  {
   return true;
  }
 }
 if (Root->Right)
 {
  return Search(Root->Right, Data, Node);
 }
 return false;
}
. Всё соответствует логике функции и её подзадачи. А если решаешь что то монструозное, то не удивляйся такому же программному тексту.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
03.01.2014, 11:16  [ТС] 11
Tulosba, ой, плохой пример привел.
Немного отредактирую:
функция возвращает bool, если взяла на себя работу и false, если не может обработать некоторые данные. Выпрыгнуть из всей рекурсии надо тогда, когда данные удовлетворяют некоторому условию. Не имеет разницы, что вернут функции (и вернут ли они вообще что-то) в этом случае.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool f1()
{
/*что-то, что решает, может ли функция обработать данные и, если может, обрабатывает и возвращает true*/
return f2();
}
bool f2()
{
/*что-то, что решает, может ли функция обработать данные и, если может, обрабатывает и возвращает true*/
if (..) //ни f1, ни f2 не могут обработать данные, выпрыгиваем, иначе бесконечная рекурсия
goto HERE;
return f1();
}
int main()
{
f1();
HERE:
doSomethingElse();
}
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
03.01.2014, 11:27 12
Можно, кстати, и в макрос запихать условный return. Параметр макроса подставляется в правую часть оператора присваивания и если присвоилось true, то return. А выход из рекурсии с разворотом стека можно делать только при низкоуровневой оптимизации, пока до неё не дошёл, всякий выход из рекурсии должен быть возвратом из всех экземпляров всех функций по цепочке.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
03.01.2014, 11:49  [ТС] 13
taras atavin, исключения бы подходили идеально, но использовать их нельзя ;d
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
03.01.2014, 13:09 14
Согласен, но так делать не надо.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.01.2014, 13:39 15
Цитата Сообщение от nexen Посмотреть сообщение
ой, плохой пример привел.
Потому что надуманный.
По коду видим чередование f1, f2. Отсюда, как мне кажется, имеет смысл реализовать вовсе без рекурсии, циклом:
C++
1
2
3
4
do
{
    f1();
} while( f2() );
Если нужно с передачей аргументов внутрь функций.
0
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
03.01.2014, 13:47  [ТС] 16
Tulosba,
Цитата Сообщение от nexen Посмотреть сообщение
Да и так забавно, когда описываешь задачу, а тебе говорят:"изменяй условия задачи! Не используй это и это, а используй это и это" :\
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
03.01.2014, 13:53 17
Цитата Сообщение от nexen Посмотреть сообщение
Да и так забавно, когда описываешь задачу, а тебе говорят:"изменяй условия задачи! Не используй это и это, а используй это и это" :\
Не путай задачу с количеством ифов.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.01.2014, 13:58 18
nexen, когда условие задачи состоит в том, чтобы забить шуруп отверткой, то условие задачи безусловно надо менять.
1
2719 / 1773 / 187
Регистрация: 05.06.2011
Сообщений: 5,132
03.01.2014, 14:04 19
Ну, в Цэ есть ещё setjump/longjump, так, кажись. По сути дела, исключения для бедных — для бедных Цэшников. Если и этого нельзя, только if — насколько помню, обычный goto разрешён только в пределах одной функции. Именно потому, что не делает возвратов.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
03.01.2014, 14:10 20
Если ты корень диска что то кинул, то это ещё не значит, что и остальные поступили также. У линуксоидов, например, нет самого диска. Да и на винде очень не рекомендуется захламлять корень.
0
03.01.2014, 14:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.01.2014, 14:10
Помогаю со студенческими работами здесь

Решение задачи с применением нескольких функций
Помогите с решением :) Написать программу решением задачи с помощью нескольких функций. Значения...

Программирование задач с использованием нескольких функций
всем доброго времени суток! вроде код правильный, помогите найти ошибку!! #include <iostream.h>...

Программа с возвратом из функций нескольких значений
Как переделать эту на программу с возвратом из функций нескольких значений? void main() {...

Шаблоны функций при компиляции нескольких файлов
Добрый день, форумчане! Ситуация следующая: есть проект на VS2015. В сторонней от него папке...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru