break в С++ (Выход из функции)
Модератор: Модераторы разделов
break в С++
Где, кроме switch и for применима команда break? Как сделать моментальный выход из функции по типу break?
Re: break в С++
return
Сохранятся все вычисления в функции до ретёна? А, если функция void?
Re: break в С++
Цитата(gavrasio @ Jul 19 2015, в 16:34) *
Сохранятся все вычисления в функции до ретёна?
Зачем им куда-то сохраняться?
Если глобальные переменные там. Если я обрываю работу функции, как это восприймет компилятор? Сохранит всё, что было до прерывания, или полностью проигнорирует работу функции?
Re: break в С++
Лучше всего, если вы сами проведёте несколько экспериментов, и непосредственно увидите как именно действует return во всех интересующих вас ситуациях. Ну а пока давайте порассуждаем. Рассмотрим например такой код:gavrasio писал(а): ↑19.07.2015 17:26
Цитата(gavrasio @ Jul 19 2015, в 16:34) *
Сохранятся все вычисления в функции до ретёна?
Зачем им куда-то сохраняться?
Если глобальные переменные там. Если я обрываю работу функции, как это восприймет компилятор? Сохранит всё, что было до прерывания, или полностью проигнорирует работу функции?
Код: Выделить всё
static int counter = 0;
void read_counter_and_return_if_counter_not_less_ten() {
scanf("%d", &counter);
if(counter >= 10)
return;
printf("counter < 10\n");
}
Предположим, что return работает полностью игнорируя функцию. Что тогда случится при вызове этой функции? Сработает ли printf или нет? Чтобы компилятору (или рантайму, неважно) узнать, надо ли вызывать printf, нужно знать значение счётчика counter. При этом условие идёт после ввода этого самого counter с клавиатуры. Таким образом чтобы узнать нужно ли делать return, сначала нужно выполнить весь код функции до него. И назад это уже никак не откатишь - для этого понадобилась бы машина времени или хотя бы стирание памяти человеку, вводившему значение counter. Значит, таким образом return работать не может.
Re: break в С++
Лучше всего, если вы сами проведёте несколько экспериментов, и непосредственно увидите как именно действует return во всех интересующих вас ситуациях.
Делал это. Потому и с Вами. Не любит С++ go to. Если я зделаю метку и безусловный переход, по-моему всё сохранится. А, если я не знаю куда поставить метку? Тут как-то с ссылками поработать надо?
Делал это. Потому и с Вами. Не любит С++ go to. Если я зделаю метку и безусловный переход, по-моему всё сохранится. А, если я не знаю куда поставить метку? Тут как-то с ссылками поработать надо?
Re: break в С++
gavrasio писал(а): ↑19.07.2015 17:26
Цитата(gavrasio @ Jul 19 2015, в 16:34) *
Сохранятся все вычисления в функции до ретёна?
Зачем им куда-то сохраняться?
Если глобальные переменные там. Если я обрываю работу функции, как это восприймет компилятор? Сохранит всё, что было до прерывания, или полностью проигнорирует работу функции?
Ну, компилятор ведь вначале соберет весь код, причем вместе с return. И код будет корректным, если он уж его собрал. И выполнение будет вполне предсказуемым.
Если, конечно, ретурном оборвать оставшееся в функции, то компиляторр выкинет warning. И оное, естественно, будет недоступным, собрет его компилятор в код или просто выкинет.
Лучше не теоризировать, а попробовать. Код + отладчик никто не отменял.
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
Компилятор одинаково работает с функциями независимо от того, в каком месте встречается return. То есть по завершении значения стековых переменных теряются, глобальных и статических — сохраняются.
Что-то ни разу я подобного не наблюдал. Или имеется в виду безусловный return посреди функции? Так на фига он нужен?:
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: break в С++
Bizdelnick писал(а): ↑19.07.2015 21:08
Компилятор одинаково работает с функциями независимо от того, в каком месте встречается return. То есть по завершении значения стековых переменных теряются, глобальных и статических — сохраняются.
Что-то ни разу я подобного не наблюдал. Или имеется в виду безусловный return посреди функции? Так на фига он нужен?:
Я именно про "безусловный return посреди функции". Он бывает нужен во время отладки. Например, функция длинная и надо временно заблокировать часть. Но, потом можно про это забыть, а компилятор не забудет и напомнит. Да, можно отрезать комментарием или препроцессором, но тогда уже точно никто не напомнит забывчивому программеру.
Re: break в С++
Bizdelnick писал(а): ↑19.07.2015 21:08Компилятор одинаково работает с функциями независимо от того, в каком месте встречается return. То есть по завершении значения стековых переменных теряются, глобальных и статических — сохраняются.
Вот такая программка
Код: Выделить всё
#include<iostream>
using namespace std;
int a;
int option(int a)
{
cout<<"a=";cin>>a;cout<<endl;
if (a==0)
return a ;
cout<<"a=";cin>>a;cout<<endl;
if (a==0)
return a;
cout<<"a=";cin>>a;cout<<endl;
return a;
}
int main()
{
cout<<"GAVRASIO"<<endl;
option( a);
cout<<"a after="<<a<<endl;
int z;
cin>>z;
return 0;
}
возвращает для а всегда ноль, хотя я хотел, что бы она возвращала записанное значение
Код: Выделить всё
[extract@0 drive_c]$ ./a.out
GAVRASIO
a=5
a=6
a=7
a after=0
1
[extract@0 drive_c]$
Re: break в С++
Так вы ее по значению передаете, как же она вернется обратно-то...
По указателю (C/C++):
По ссылке (C++):
По указателю (C/C++):
Код: Выделить всё
int option (int *a) {
...
option(&a);
По ссылке (C++):
Код: Выделить всё
int option (int &a) {
...
option(a);
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
Вы здесь определили глобальныю переменную, а потом переопределили её как аргумент функции (стековую переменную). Поэтому внутри функции option() a — это другая переменная.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: break в С++
Bizdelnick писал(а): ↑15.12.2015 19:20
Вы здесь определили глобальныю переменную, а потом переопределили её как аргумент функции (стековую переменную). Поэтому внутри функции option() a — это другая переменная.
Согласен. Без определителя или ссылки здесь не обойтись. Но безоговорочный return не проходит по всякому, если функция определена с int, компилятор требует возвращаемое значение. А хотелось бы выйти из функции при определённом условии без всяких дополнительных (!) условий.
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
Так не бывает. Или Вы определяете тип функции и всегда возвращаете значение, или определяете её как void и ничего не возвращаете ни при каких условиях.
Если нужно сообщить вызывающей функции об ошибке, возвращайте какое-нибудь заведомо некорректное в данном случае значение (обычно возвращают отрицательные значения там, где уместны только положительные) и обрабатывайте его соответствующим образом. Ну или кидайте исключение, хотя они на то и исключения, чтобы использовать их только в исключительных ситуациях, а Вы, как я понимаю, говорите о нормальной работе программы.
Upd. Ещё один способ — возвращать не int, а std::pair<int, int>, где первое значение — введённое число, а второе — признак ошибки, и если оно отлично от нуля, первое обрабатывать не нужно.
Если нужно сообщить вызывающей функции об ошибке, возвращайте какое-нибудь заведомо некорректное в данном случае значение (обычно возвращают отрицательные значения там, где уместны только положительные) и обрабатывайте его соответствующим образом. Ну или кидайте исключение, хотя они на то и исключения, чтобы использовать их только в исключительных ситуациях, а Вы, как я понимаю, говорите о нормальной работе программы.
Upd. Ещё один способ — возвращать не int, а std::pair<int, int>, где первое значение — введённое число, а второе — признак ошибки, и если оно отлично от нуля, первое обрабатывать не нужно.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: break в С++
Я так понимаю, что мой вопрос не может разрешён из-за правил синтаксиса языка С++. На нижнем его уровне.
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
А Вы можете сформулировать свой вопрос более конкретно? В виде реального практического примера. У меня такое подозрение, что Вы пытаетесь найти решение, неприемлемое не только и не столько из-за ограничений языка, сколько из-за нелогичности самого подхода.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: break в С++
Мне советовали здесь сделать так
То есть безусловный выход из функции. Я это и хочу сделать. Но не получается.
Код: Выделить всё
#include<iostream>
using namespace std;
int a;
int option(int a)
{
a=a*4;
cin>>a;
if (a==24)
return;
a=a*5;
}
int main()
{
cout<<"GAVRASIO"<<endl;
option( a);
cout<<"a after="<<a<<endl;
int z;
cin>>z;
return 0;
}
То есть безусловный выход из функции. Я это и хочу сделать. Но не получается.
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
Ну Вы же никак не используете возвращаемое значение. Объявите её void.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: break в С++
Но она обозначена как int. А мне надо из неё выйти. Без всяких дополнительных условий.
- Stauffenberg
- Сообщения: 2042
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: break в С++
Код: Выделить всё
g++ test.cpp -o test_cpp
test.cpp: In function ‘int option(int)’:
test.cpp:11:3: error: return-statement with no value, in function returning ‘int’ [-fpermissive]
return;
^
Это значит, что ожидатеся int. а на деле void.
Попробуйте вот так:
Код: Выделить всё
#include<iostream>
using namespace std;
int a;
void option(int a)
{
a=a*4;
cin>>a;
if (a==24)
return;
a=a*5;
}
int main()
{
cout<<"GAVRASIO"<<endl;
option(a);
cout<<"a after="<<a<<endl;
int z;
cin>>z;
return 0;
}
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
Зачем? Если Вы не обрабатываете возвращаемое значение, ничто не мешает объявить её void. Если бы Вы его обрабатывали, то его надо было бы обязательно возвращать, потому что иначе нечего было бы обрабатывать. Безотносительно каких-то ограничений, накладываемых C++.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- Stauffenberg
- Сообщения: 2042
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: break в С++
Тут два варианта - либо Вы возвращаете ничего, тогда объявляете ее как void. Либо Вы возвращаете какое-то число, тогда объявляете ее как int. Во втором случае естественно надо вернуть какое-то число (просто return вернет ничего, или, как говорят программисты в Германии, - квашеную капусту).
Проблема в том, что нельзя из функции, от которой ожидается int, получить void. Если Вам не важен результат, то, как Вам уже посоветовали, возвращайте заранее известное значение, которое в main будет интерпретированно как неинтересное (например отрицательное число).
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Re: break в С++
Stauffenberg писал(а): ↑15.12.2015 23:56
Тут два варианта - либо Вы возвращаете ничего, тогда объявляете ее как void. Либо Вы возвращаете какое-то число, тогда объявляете ее как int. Во втором случае естественно надо вернуть какое-то число (просто return вернет ничего, или, как говорят программисты в Германии, - квашеную капусту).
Вернёмся к началу темы. Как выйти из функции по типу брейк? Безусловного выхода из любой функции, я так понял, нет. Ретьон накладывает свои условия, а это уже не безусловное выхождение. Синтаксис С++ это не позволяет. Так?
- Stauffenberg
- Сообщения: 2042
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: break в С++
Дело не в этом. Дело в том, что безусловный выход, о котором Вы говорите, обозначает ничего не возвращать назад. Компилятор не любит функции, которые должны вернуть, к примеру, int, а возвращают ничего, понимаете?
Если Вам нужно перезаписать глобальную переменную, то попробуйте что-то типа этого:
Код: Выделить всё
include<iostream>
using namespace std;
int a = 1;
void option()
{
a=a*4;
cin>>a;
if (a==24)
return;
a=a*5;
}
int main()
{
cout<<"GAVRASIO"<<endl;
option();
cout<<"a after="<<a<<endl;
int z;
cin>>z;
return 0;
}
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
Вы забываете о том, что сама функция была откуда-то вызвана. И после выхода из неё Вы вернётесь в вызывающую функцию, которая должна продолжить работу. И если эта вызывающая функция ждёт возвращаемого значения, надо ей это значение дать. Допустим, у Вас в main() было бы такое:
Код: Выделить всё
int b = option(a);
Синтаксис C++ здесь совершенно ни при чём, это логика процедурного программирования.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: break в С++
Это уже проверено. Работает нормально. Мой вопрос был: Выход из любой(!) функции. Есть void , есть int. Корректно выйти из любой. Просто выйти по условию, не взирая ни на что. Можно это? Я приводил несколько кодов. Всё работает. Но мне хочется, чтобы работало согласно моему вопросу. Согласен, синтаксис здесь непричём. Здесь прцедура!
- Stauffenberg
- Сообщения: 2042
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: break в С++
нет
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
- Bizdelnick
- Модератор
- Сообщения: 20796
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: break в С++
Да прочитайте же Вы то, что Вам написали, в конце концов.
Можно, можно выйти из любой функции, ничего не возвращая. Но работа вызывающей функции тоже будет нарушена. Можно кинуть исключение, можно вообще вызвать exit() или abort(). Формально никто не запрещает так делать.
Можно, можно выйти из любой функции, ничего не возвращая. Но работа вызывающей функции тоже будет нарушена. Можно кинуть исключение, можно вообще вызвать exit() или abort(). Формально никто не запрещает так делать.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: break в С++
Я с Вами согласен. Посидел просто в консоли, перебрал все варианты( совет Форума). Всё, что Вы говорили выше, - всё правильно. Там насчёт литературы были ссылки, но одни говорят, что то дерьмо, другие молятся на те книжки.Я сижу на трёх неделях С++.