В языке С определены четыре оператора перехода: return , goto , break и continue . Операторы return и goto можно использовать в любом месте внутри функции. Операторы break и continue можно использовать в любом из операторов цикла. Как указывалось ранее в этой главе, break можно также использовать в операторе switch .
Оператор return
Оператор return используется для выхода из функции. Отнесение его к категории операторов перехода обусловлено тем, что он заставляет программу перейти в точку вызова функции. Оператор return может иметь ассоциированное с ним значение, тогда при выполнении данного оператора это значение возвращается в качестве значения функции. В функциях типа void используется оператор return без значения.
Стандарт С89 допускает наличие оператора return без значения, даже если тип функции отличен от void . В этом случае функция возвращает неопределенное значение. Но что касается языков С99 и C++, если тип функции отличен от void , то ее оператор return обязательно должен иметь значение. Конечно, и в программе на С89 отсутствие возвращаемого значения в функции, тип которой отличен от void , является признаком плохого стиля!
Работа с файлами с++. Запись в файл. c++ ofstream. Изучение С++ для начинающих. Урок #115
Общая форма оператора return следующая:
return выражение;
Выражение присутствует только в том случае, если функция возвращает значение. Это значение выражения становится возвращаемым значением функции.
Внутри функции может присутствовать произвольное количество операторов return . Выход из функции происходит тогда, когда встречается один из них. Закрывающаяся фигурная скобка > также вызывает выход из функции. Выход программы на нее эквивалентен оператору return без значения. В этом случае функция, тип которой отличен от void , возвращает неопределенное значение.
Функция, определенная со спецификатором void , не может содержать return со значением. Так как эта функция не возвращает значения, в ней не может быть оператора return , возвращающего значение. Более подробно return рассматривается в главе 6.
Оператор goto
Кроме goto , в языке С есть другие операторы управления (например break , continue ), поэтому необходимости в применении goto практически нет. В результате чрезмерного использования операторов goto программа плохо читается, она становится «похожей на спагетти». Чаще всего такими программами недовольна администрация фирм, производящих программный продукт. То есть оператор goto весьма непопулярен, более того, считается, что в программировании не существует ситуаций, в которых нельзя обойтись без оператора goto . Но в некоторых случаях его применение все же уместно. Иногда, при умелом использовании, этот оператор может оказаться весьма полезным, например, если нужно покинуть глубоко вложенные циклы [1] . В данной книге оператор goto рассматривается только в этом разделе.
Для оператора goto всегда необходима метка. Метка — это идентификатор с последующим двоеточием. Метка должна находится в той же функции, что и goto , переход в другую функцию невозможен. Общая форма оператора goto следующая:
Программирование на Си — Урок 12 — Пишем первую простую игру про голодную собаку
goto метка; . . . метка:
Метка может находиться как до, так и после оператора goto . Например, используя оператор goto , можно выполнить цикл от 1 до 100:
x = 1; loop1: x++; if(x<=100) goto loop1;
Оператор break
Оператор break применяется в двух случаях. Во-первых, в операторе switch с его помощью прерывается выполнение последовательности case (см. раздел «Оператор выбора — switch» ранее в этой главе). В этом случае оператор break не передает управление за пределы блока. Во-вторых, оператор break используется для немедленного прекращения выполнения цикла без проверки его условия, в этом случае оператор break передает управление оператору, следующему после оператора цикла.
Когда внутри цикла встречается оператор break , выполнение цикла безусловно (т.е. без проверки каких-либо условий.) прекращается и управление передается оператору, следующему за ним. Например, программа
#include int main(void) < int t; for(t=0; treturn 0; >
выводит на экран числа от 0 до 10. После этого выполнение цикла прекращается оператором break , условие t < 100 при этом игнорируется.
Оператор break часто используется в циклах, в которых некоторое событие должно вызвать немедленное прекращение выполнения цикла. В следующем примере нажатие клавиши прекращает выполнение функции look_up() :
void look_up(char *name) < do < /* поиск имени ‘name’ */ if(kbhit()) break; >while(!found); /* process match */ >
Библиотечная функция kbhit() возвращает 0, если клавиша не нажата (то есть, буфер клавиатуры пуст), в противном случае она возвращает ненулевое значение. В стандарте С функция kbhit() не определена, однако практически она поставляется почти с каждым компилятором (возможно, под несколько другим именем).
Оператор break вызывает выход только из внутреннего цикла. Например, программа
for(t=0; t >
100 раз выводит на экран числа от 1 до 9. Оператор break передает управление внешнему циклу for .
Если оператор break присутствует внутри оператора switch , который вложен в какие-либо циклы, то break относится только к switch , выход из цикла не происходит.
Функция exit()
Функция exit() не является оператором языка, однако рассмотрим возможность ее применения. Аналогично прекращению выполнения цикла оператором break , можно прекратить работу программы и с помощью вызова стандартной библиотечной функции exit() . Эта функция вызывает немедленное прекращение работы всей программы и передает управление операционной системе.
Общая форма функции exit() следующая:
void exit (int код_возврата);
Значение переменной код_возврата передается вызвавшему программу процессу, обычно в качестве этого процесса выступает операционная система. Нулевое значение кода возврата обычно используется для указания нормального завершения работы программы. Другие значения указывают на характер ошибки. В качестве кода возврата можно использовать макросы EXIT_SUCCESS и EXIT_FAILURE (выход успешный и выход с ошибкой). Функция exit() объявлена в заголовочном файле .
Функция exit() часто используется, когда обязательное условие работы программы не выполняется. Рассмотрим, например, компьютерную игру в виртуальной реальности, использующую специальный графический адаптер. Главная функция main() этой игры выглядит так:
#include int main(void) < if(!virtual_graphics()) exit(1); play(); /* . */ >/* . */
Здесь virtual_graphics() возвращает значение ИСТИНА, если присутствует нужный графический адаптер. Если требуемого адаптера нет, вызов функции exit(1) прекращает работу программы.
В следующем примере в новой версии ранее рассмотренной функции menu() вызов exit() используется для выхода из программы и возврата в операционную систему:
void menu(void) < char ch; printf(«1. Проверка правописанияn»); printf(«2. Коррекция ошибокn»); printf(«3. Вывод ошибокn»); printf(«4. Выходn»); printf(» Введите Ваш выбор: «); do < ch = getchar(); /* чтение клавиши */ switch(ch) < case ‘1’: check_spelling(); break; case ‘2’: correct_errors(); break; case ‘3’: display_errors(); break; case ‘4’: exit(0); /* Возврат в ОС */ >> while(ch!=’1′ ch!=’2′ ch!=’3′); >
Оператор continue
Можно сказать, что оператор continue немного похож на break . Оператор break вызывает прерывание цикла, a continue — прерывание текущей итерации цикла и осуществляет переход к следующей итерации. При этом все операторы до конца тела цикла пропускаются. В цикле for оператор continue вызывает выполнение операторов приращения и проверки условия цикла. В циклах while и do-while оператор continue передает управление операторам проверки условий цикла. В следующем примере программа подсчитывает количество пробелов в строке, введенной пользователем:
/* Подсчет количества пробелов */ #include int main(void) < char s[80], *str; int space; printf(«Введите строку: «); gets(s); str = s; for(space=0; *str; str++) < if(*str != ‘ ‘) continue; space++; >printf(«%d пробеловn», space); return 0; >
Каждый символ строки сравнивается с пробелом. Если сравниваемый символ не является пробелом, оператор continue передает управление в конец цикла for и выполняется следующая итерация. Если символ является пробелом, значение переменной space увеличивается на 1.
В следующем примере оператор continue применяется для выхода из цикла while путем передачи управления на условие цикла:
void code(void) < char done, ch; done = 0; while(!done) < ch = getchar(); if(ch==’$’) < done = 1; continue; >putchar(ch+1); /* печать следующего в алфавитном порядке символа */ > >
Функция code предназначена для кодирования сообщения путем замены каждого символа символом, код которого на 1 больше кода исходного символа в коде ASCII. Например, символ А заменяется символом В (если это латинские символы.). Функция прекращает работу при вводе символа $ . При этом переменной done присваивается значение 1 и оператор continue передает управление на условие цикла, что и прекращает выполнение цикла.
[1] Уже одно это (чрезмерная вложенность и неожиданный выход сразу из нескольких циклов) может свидетельствовать о плохой структуре программы.
Источник: t-r-o-n.ru
Как мне выполнить выход из консольной программы C ++?
Использовать выход нехорошо. Он ломает все те объекты RAII, которые мы правильно построили. Гораздо приятнее вернуться к основному. Если, с другой стороны, программа повреждена, вам действительно следует вызвать std::terminate() — Мартин Йорк
Проголосовали против, потому что в нем отсутствует оговорка о том, как он разрушает прекрасный мир RAII. — Себастьян Мах
Пока вы может называть exit() (и, возможно, потребуется сделать это, если ваше приложение столкнется с какой-либо фатальной ошибкой), самый простой способ выйти из программы — вернуться из main() :
int main() < // do whatever your program does >// function returns and exits program
Когда вы звоните exit() , объекты с автоматическим сроком хранения (локальные переменные) не уничтожаются до завершения работы программы, поэтому вы не получаете надлежащей очистки. Этим объектам может потребоваться очистить любые ресурсы, которыми они владеют, сохранить любые ожидающие изменения состояния, завершить все запущенные потоки или выполнить другие действия, чтобы программа завершилась корректно.
ответ дан 27 окт ’10, 23:10
И если вам нужно выйти из глубины программы, блок try/catch в main может быть предпочтительнее exit() . Это действительно пережиток Си. — Марк Рэнсом
Помните, что это определяется реализацией, когда стек раскручивается, если исключение покидает main, не будучи перехваченным. Так что безопаснее всего перехватывать все исключения в main, а затем перебрасывать. Я говорю повторно, поскольку некоторые ОС (Windows) перехватывают неперехваченное исключение и делают приятные вещи для разработчика (я не уверен, что это относится только к отладке). — Мартин Йорк
Есть несколько способов заставить вашу программу завершить работу. Какой из них подходит, зависит от того, почему вы хотите, чтобы ваша программа завершилась. В подавляющем большинстве случаев это должно происходить путем выполнения оператора return в вашей основной функции. Как в следующем.
int main()
Как определили другие, это позволяет правильно уничтожить все ваши переменные стека, чтобы правильно очистить их. Это очень важно.
Если вы обнаружили ошибку где-то глубоко в своем коде и вам нужно выйти, вы должны создать исключение, чтобы вернуться к основной функции. Как в следующем.
struct stop_now_t < >; void f() < // . if (some_condition()) throw stop_now_t(); // . >int main() < try < f(); >catch (stop_now_t return 1; >return 0; >
Это приводит к раскручиванию стека и уничтожению всех ваших переменных стека. Еще очень важно. Обратите внимание, что уместно указывать на ошибку ненулевым возвращаемым значением.
Если в маловероятном случае, когда ваша программа обнаруживает условие, указывающее на то, что выполнение каких-либо операторов больше небезопасно, вам следует использовать std::abort(). Это приведет к внезапной остановке вашей программы без дальнейшей обработки. std::exit() аналогичен, но может вызывать обработчики atexit, что может быть плохо, если ваша программа достаточно загружена.
ответ дан 28 окт ’10, 05:10
Примечание: std::abort() следует использовать для немедленного прекращения. std::terminate() должен использоваться средствами обработки исключений C++ только в случае сбоя обработки исключений; вы не должны вызывать его напрямую. — Джеймс МакНеллис
На мой взгляд, stop_now_t тип исключения является злоупотреблением системой исключений. Его использование будет означать, что вы используете исключения для нормального потока управления (что обычно плохо). Функция не должна генерировать исключение, зная, что оно будет перехвачено только в main() ; он должен генерировать исключение, предполагая, что оно может быть перехвачено любым вызывающим объектом, который может обработать исключение. — Джеймс МакНеллис
Джеймс, вы меня подключили к std::terminate(). Да, std::abort — лучший выбор. Уместно ли исключение типа stop_now_t, зависит от того, как вы структурировали свой алгоритм. Учитывая, что в таком простом примере это может быть плохим способом сделать это. Но я просто пытался проиллюстрировать, как можно использовать исключения. — Боуи Оуэнс
ответ дан 27 окт ’10, 23:10
Проголосуйте за отсутствующий отказ от ответственности о том, как это обходит счастливый мир RAII. — Себастьян Мах
Вы действительно отвечаете на downvote-события в течение 2 секунд? Потому что я еще объяснял причину, а ты уже кричишь «Downvoter: Почему?». / Хорошо. Вы снова удалили свой крик, сведя на нет часть времени, которое я потратил/потратил впустую. — Себастьян Мах
Заявление о расходах/отходах было о моем втором ответе, который был ответом на ваш вопрос «почему?». Обычно я комментирую свои отрицательные голоса, но я не согласен с тем, что все отрицательные голоса должны быть прокомментированы, например, когда они явно невежественны или когда уже есть объяснение другого голосующего против, которое соответствует моему мнению. В любом случае, я обычно не намерен оскорблять, мои голоса всегда против (качества) ответа, а не против человека;) — Себастьян Мах
Разрешение потока выполнения уйти main by возврат значения или разрешение выполнения до конца функции это то, как программа должна завершаться, кроме как при неисправимых обстоятельствах. Возврат значения необязателен в C++, но я обычно предпочитаю возвращать EXIT_SUCCESS находится в cstdlib (зависимое от платформы значение, указывающее на успешное выполнение программы).
#include int main(int argc, char *argv[])
Однако, если ваша программа достигает неисправимого состояния, она должна генерировать исключение. Однако важно осознавать последствия этого. Не существует общепринятых передовых практик для принятия решения о том, что должно или не должно быть исключением, но есть некоторые общие правила, о которых вам необходимо знать.
Например, генерация исключения из деструктора почти всегда является ужасной идеей, потому что уничтожаемый объект мог быть уничтожен из-за того, что исключение уже было генерировано. Если выдается второе исключение, terminate вызывается, и ваша программа останавливается без выполнения какой-либо дальнейшей очистки. Ты может использование uncaught_exception чтобы определить, безопасно ли это, но обычно лучше никогда не позволять исключениям покидать деструктор.
Хотя, как правило, функции, которые вы вызываете, но не написали, всегда могут вызывать исключения (например, new будет бросать std::bad_alloc если он не может выделить достаточно памяти), начинающим программистам часто бывает трудно отслеживать или даже знать обо всех специальных правилах, связанных с исключениями в C++. По этой причине я рекомендую использовать их только в ситуациях, когда у вашей программы нет разумного способа продолжить выполнение.
#include #include #include int foo(int i) < if (i != 5) < throw std::runtime_error(«foo: i is not 5!»); >return i * 2; > int main(int argc, char *argv[]) < try < foo(3); >catch (const std::exception std::cout return EXIT_SUCCESS; >
exit является пережитком C и может привести к тому, что объекты с автоматическим хранением не будут очищаться должным образом. abort и terminate эффективно заставляет программу совершить самоубийство и определенно не очистит ресурсы.
Что бы вы ни делали, не используйте исключения, exit или abort / terminate как костыль для написания правильно структурированной программы. Сохраните их для исключительных ситуаций.
ответ дан 23 мая ’17, 12:05
Источник: stackovergo.com
Exit – прекращает выполнение программы
Функция exit прекращает вызываемый процесс. Перед выходом из процесса все файлы закрываются, записывается буферный вывод (ждущий вывода) и вызываются зарегистрированные «функции выхода» (объявленные в функции atexit). В любом случае, для вызываемого процесса обеспечивается аргумент status, который представляет собой статус выхода для данного процесса. Обычно, значение, равное нулю, используется для обозначения нормального выхода из процесса, а ненулевое значение обозначает какие-либо ошибки. Оно устанавливается одним из следующих:
EXIT_SUCCESS — нормальное завершение.
EXIT_FAILURE — ненормальное завершение. Сообщает операционной системе, что программа завершилась с ошибкой.
Возвращаемое значение
Переносимость
Поддерживается в системах UNIX и определена в ANSI C.
Пример
#include #include #include int main(void)
Источник: cubook.pro