Цикл — разновидность управляющей конструкции в высокоуровневых языках программирования, предназначенная для организации многократного исполнения набора инструкций. Также циклом может называться любая многократно исполняемая последовательность инструкций, организованная любым способом (например, с помощью условного перехода).
В языке Си существует 3 вида циклов.
while( проверка условия );
do<>while( проверка условия );
for( ; проверка условия ; )<>
while(); — перед выполнением тела, идет проверка какого-либо условия,результатом проверки которой является — выполнять тело цикла или нет. предусловие.
do<>while(); проверка условия выполняется в конце тела. постусловие
for( ;проверка условия ; )<> — проверка условия выполняется в конце тела. предусловие
Цикл for имеет 3 секции, разделенных с помощью ;.
for( инициализация (выполняется один раз, в начале цикла);
проверка условия(выполняется каждый раз перед выполнением тела) ;
выполняется каждый раз после выполнения тела).
Уроки C++ / Первая программа на С++
В инициалицации можно объявлять переменные(счетчики циклов), или инициализировать какие-то глобальные счетчики каким-то стартовым значением.
Телом цикла называется блок <>, внутри которого находятся инструкции, которые нужно выполнять циклично (определенное колличество раз).
Если инструкций больше чем одна, и они разделены ; то тело оборачивается блоком <>, если же инструкция одна то тело в эти скобки можно не оборачивать. Это справедливо для циклов с предусловием.
Под проверкой условия подразумевается сравнение какого-либо выражение с 0. Если результат выполнения выражения равен 0. Значит тело цикла не выполнять. Смотрите примеры ниже.
#include int main() int i = 0; while(i) printf(«loop 1n»); // блок <> не обязателен, одна инструкция i = 1; while(i 3) printf(«loop 2 : %in», i);// блок <> обязателен, больше одной инструкции i++; > do printf(«loop 3 : %in», i); i—; >while(i); for(i = 3; i; i—) printf(«loop 4 : %in», i); // блок <> не обязателен, одна инструкция for(int i1 = 0, j1 = 10; i1 != j1; i1++, j1—) printf(«loop 5 : %i — %in», i1, j1); return 0; >
Циклы for обычно используются когда есть конкрентое понятие — счетчик итераций, и мы знаем сколько раз должно выполниться тело цикла. Как раз дя этого и есть 3 секции. В других случаях используются оставшиеся циклы. К примеру бесконечный цикл в языке Си выглядит так:
#include int main() while(1) // come instructions > return 0; >
Также существуют операторы перехода — break, continue, return, goto
break — завершает выполнение цикла.
int main() int i = 0; while(1) if(i > 100) break; // завершить цикл ++i; > return 0; >
continue — выполняет переход в конец тела цикла(то есть после выполнения этого оператора, все что после него игнорируется, происходит переход в конец цикла, и далее начинается новая итерация). В примере ниже, цикл бесконечный, так как при выполнении условия i>2 происходит переход в конец тела цикла, то есть игнорируется увеличение счетчика, а условием выхода из цикла является i==11.
Уничтожаю C++
int main() int i = 0; while(i != 11) if(i > 2) continue; ++i; > return 0; >
return — завершает выпонение не то что цикла, а целой функции. Если функция типа void то нужно вызвать просто return; иначе вернуть выражение того типа каким является тип функции.
void foo_a(int aCounterStart, int aCounterEnd, int aExtraCondition) for(int i = aCounterStart; i aCounterEnd; ++i) if(i == aExtraCondition) return; > > int foo_b(int aCounterStart, int aCounterEnd, int aExtraCondition) for(int i = aCounterStart; i aCounterEnd; ++i) if(i == aExtraCondition) return -1; > return 1; > int main() foo_a(0, 4, 4); foo_b(0, 4, 2); return 0; >
goto — оператор перехода, использование которого я крайне не рекомендую, если на это нет серьезных причин. Причина в том, что использование этого оператора, без веских на то оснований, может затруднять чтение исходного кода программы, затрудняет его понимание, и т.д. что приводит к ошибкам.
Переход осуществляется в рамках одной функции, из одной функции перейти в другую с помощью goto нельзя. Ниже можете ознакомится с циклом for и его аналогом с помощью оператора goto:
#include int main() int i = 0; for(i = 0; i 10; ++i) printf(«%in», i); printf(«—————————————-nn»); goto init; init: i = 0; goto check_condition; check_condition: if(i 10) goto loop_body; else goto loop_exit; loop_body: printf(«%in», i); goto end_body; end_body: ++i; goto check_condition; loop_exit: return 0; >
Источник: cppprosto.blogspot.com
Как закончить программу в си
«Написать программу, которая позволяет пользователю пополнять счет через терминал.
В конце программы пользователю предоставляется выбор: завершить программу или запустить вновь.»
После ввода «y» программа должна выйти из цикла и завершиться, но у меня получается.
Пробовал разные способы — никак.
И преподаватель говорила, что это делается с помощью «getch()»
int s,a; char c=’y’,g[1]; s=0; do < a=0; printf(«Введите сумму,на которую нужно пополнить счётn»); scanf(«%d», printf(«Ваш счёт пополнен на %d n»,s); printf(«Завершить программу? y/n? n»); scanf(«%s»,g); if(g==’y’) a=27; else a=0; >while (a != 27); a=getch();
Регистрация: 04.02.2011
Сообщений: 4,429
Можно и так, только придется нажать y и Enter
if(g==’y’) a=27;
Ну а эти реверансы зачем? Почему в while не проверять саму g ?
Последний раз редактировалось digitalis; 08.10.2019 в 10:33 .
Участник клуба
Регистрация: 21.11.2007
Сообщений: 1,063
После ввода символа как ни крути Enter жать нужно.
В качестве примера по работе с выбором (y/n)
int a; a = 0; do < int k, s; std::cout if (k == ‘n’ || k == ‘N’) < std::cout > s; std::cout > while (a != 1);
Этот код без проверки корректности ввода.
I am not a wizard, I am just learning.
Последний раз редактировалось Desc; 08.10.2019 в 18:56 .
Регистрация: 04.02.2011
Сообщений: 4,429
Я давно на Си не работал, но вроде как по getchar символ сразу воспринимается прогой. Другое дело, что нужно вводить не в массив символов — сиречь строку, а в одиночный.
char c=’y’,g; s=0; g = ‘.’ ; do < printf(«Введите сумму,на которую нужно пополнить счётn»); scanf(«%d», printf(«Ваш счёт пополнен на %d n»,s); printf(«Завершить программу? y/n? n»); с=getch(); >while (с != ‘y’);
Участник клуба
Регистрация: 21.11.2007
Сообщений: 1,063
Думаю нужно слегка подправить объявление переменных
char g;
g = getch(); > while (g != ‘y’);
если выполнять в Microsoft VS тогда:
g = _getch(); > while (g != ‘y’);
_getch с подчеркиванием.
P. S.
Полагаю что вместо n можно будет жать любую клавишу.
I am not a wizard, I am just learning.
Последний раз редактировалось Desc; 08.10.2019 в 21:50 .
Источник: www.programmersforum.ru
Как в си завершить выполняющуюся программу?
Мне казалось можно использовать halt; но оказалось нет такой функции.
abort если завершение аварийное
dereferencing NULL pointer, будет segmentation fault
Вышестоящий try/catch может с легкостью поймать сгенеренное данной конструкцией исключение.
И поэтому завершения программы не будет.
Откуда инфа насчёт лёгкости?
Кроме того, вопрос про «си», в этом языке нет таких конструкций.
Ещё: вызов любой библиотечной функции тоже можно перехватить, да и что угодно можно перехватить, если на то пошло.
но согласись, что-то писать в *NULL — не очень хорошо.
В ядре Линукса одно время это было одним из предпочтительных способов вызвать аварийную остановку (kernel panic
потом добавили специальные макросы для этого.
в NT есть специальная функция для показа BSoD. Вообще, такое сообщение об ошибке будет дюже неинформативным
> такое сообщение об ошибке будет дюже неинформативным
это потому что в винде нет сорсов от ядра и ksymoops’а
Если разговор именно о Cи, то да там такой конструкции нет.
> Ещё: вызов любой библиотечной функции тоже можно перехватить
Это уже будет хак, а у хака есть дурная привычка — хаки очень не любят изменения, работу в других условиях и т.д.
try/catch — это стандартная конструкция, которая должна работать на любой платформе.
> Откуда инфа насчёт лёгкости?
Пример:
try
* int*) 0) = 0;
>
catch (. )
>
куда уж проще.
Достаточно информативно — дамп регистров, stack trace, всё как положено.
Заметим, что на x86 это раскрывается в movl $0,0 — т.е. даже регистры не портит.
А для пущей информативности перед этим printk писали какой-нибудь.
а что, какой-нибудь int 3h не прокатит?
закрытость исходников дисциплинирует
И какой код этот пример генерирует на твоей платформе?
На linux и gcc-3.2 такой же, как и без try/catch, что и следовало ожидать.
Ещё бы поганый C++ перехватывал SIGSEGV по своей инициативе.
try
* int*) 0) = 0;
throw 1;//против оптимизатора
>
catch (. )<>
Маза перестать пробовать и начать думать.
Например о том, какой код мог бы сгенерировать компилятор для перехвата SIGSEGV, и почему он так не делает.
маза придумать что-нибудь кроме segmentation fault по записи в NULL
к примеру
kill(getpidSIGKILL);
//Fortl
kill(getpidx) = raise(x)
те же яйца, но гораздо лучше выглядит
я условно написал getpid — простов названии темы не видно, что хотим завершить текущий процесс.
ИМХО, это проблема реализации языка C++ для юних-а, т.к. увеличивается недерминированность поведение программы в случае ошибки.
имхо при SIGSEGV ни о какой недетерминированности говорить не приходится
ужас, синий ужас
что же делать.
Вот флудеры
exit вполне подошел
Уважаемые флудеры, с каких пор в СИ появился try/catch?
Я не считаю с и с++ одним языком.
Источник: zavelos.ru