Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
http.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.34 Mб
Скачать

Бесконечный цикл

Одним из наиболее интересных аспектов использования цикла for является создание бесконечного цикла. Поскольку не требуется ни одна из частей, можно создать бесконечный цикл путем удаления части проверки условия. Например: for ( ; ; ) printf(" this loop will run forever. \n");

Хотя можно использовать части инициализации и увеличения, наиболее типично использование for( ; ; ) без выражений для создания бесконечного цикла.

На самом деле конструкция for( ; ; ) не обязательно создает бесконечный цикл, поскольку в теле цикла может присутствовать оператор break, при достижении которого цикл оканчивает работу. Нижеприведенная программа контролирует нажатие клавиш и, в случае достижения необходимого условия, бесконечный цикл прерывается: for ( ; ; ) { ch = getchar(); /* ввод символа */ if (ch == 'A') break; /* выход из цикла */ } printf("you typed an A"); Цикл будет работать до тех пор, пока на клавиатуре не будет набрана А.

Циклы for без тела

Оператор может быть пустым. Это означает, что тело цикла for (или любого другого цикла) может быть пустым. Это можно использовать для улучшения эффективности некоторых алгоритмов, а также для создания задержек.

Одной из наиболее типичных задач программирования является удаление пробелов из потом ввода. Например, база данных может допускать запрос типа «покажите весь баланс меньше,чем 400 ». Базе данных необходимо иметь каждое слово запроса отдельно, без пробелов. То есть процессор ввода в базу данных распознает команду «показать», но не распознает « показать».Следующий цикл удаляет все пробелы из потока, на который указывает str: for ( ; *stг  == '  ' ; str ++) ; Как видно, в цикле отсутствует тело.

В программах также часто используются циклы задержек. Следующий пример показывает, как создать задержку с помощью for: for (t = 0; t < SOME_VALUE; t++) ;

WHILE

Следующий итерационный оператор, доступный в С, - это while. Его стандартный вид следующий while (условие) оператор; где оператор - это или пустой, или простой, или составной оператор. Условием может любое выражение, имеющее в качестве истины ненулевое значение. Цикл выполняется, пока условие истинно. Когда условие становится ложным, выполняется строка, следующая за циклом. Следующий пример показывает процедуру, обрабатывающую ввод с клавиатуры, работающую пока не будет введен символ А: void wait_for_char(void) { char ch; ch = '\0'; /* инициализация ch */ while(ch!='A') ch = getchar (); } Сначала ch устанавливается в 0, Цикл while начинается с проверки ch на равенство А. Поскольку ch инициализировано нулем, проверка выдаст истину и цикл начнется. При каждом нажатии клавиши на клавиатуре условие проверяется повторно. Если введено А, условие становится ложным и цикл прекращается.

Как и цикл for, цикл while сначала выполняет проверку, то есть тело цикла может вообще не выполняться. Благодаря этому можно не выполнять отдельные проверки перед циклом. Хорошей иллюстрацией этого является функция pad(), добавляющая пробелы к концу строки до достижения предопределенной длины. Если строка уже имеет необходимую длину, то пробелы не будут добавляться: /* Добавляет пробелы к концу строки */ void pad (char *s, int length) { int l; l = strlen(s); /* определение длины */ while (l<length)  {   s[l] = ' '; /* вставка пробела */    l++;   } s [ l ] = '\0'; /* строки должны заканчиваться нулем */ } Аргументами pad() являются s - указатель на удлиняемую строку и length - желаемая длина s. Если строка s имеет длину, равную или больше length, то код внутри цикла не будет выполняться. Если длина строки s меньше чем length, то pad() добавляет требуемое число пробелов к строке. Функция strlen(), являющаяся частью стандартной библиотеки, возвращает длину строки.

Когда необходимо несколько различных условий для окончания цикла while, как правило, используют одну переменную, являющуюся результатом действия этих условий, причем значение этой переменной может устанавливаться в различных частях цикла. Например: void func1 (void) { int working; working = 1; /* т.е. истина */ while(working)  {   working=process1();    if(working)       working=process2();    if(working)       working=process3();   } } Здесь любая из трех подпрограмм может вернуть ложь и вызвать остановку цикла. В теле цикла может и не быть никаких операторов. Например: while ((ch = getchar()) != 'А'); просто зацикливается до тех пор, пока с клавиатуры не введется буква А. Если нет уверенности в использовании оператора присваивания внутри проверки выражения цикла while, надо помнить, что знак равенства на самом деле просто оператор, вычисляющий значение стоящего справа операнда.

DO/WHILE

В противоположность циклам for и while, сначала проверяющим условие, цикл do/while проверяет условие в конце. То есть, цикл do/while всегда выполняется, по крайней мере, один раз. Стандартный вид цикла do/while следующий: do { последовательность операторов; } while (условие);

Хотя в фигурных скобках нет необходимости при наличии одного оператора, они обычно используются для улучшения читабельности и устранения недоразумений (у читателя, а не у компилятора) по поводу цикла while. Данный цикл do/while осуществляет чтение чисел с клавиатуры до тех пор, пока одно из них не станет меньше либо равно 100: do { scanf ("%d", &num); } while (num > 100);

Возможно, наиболее типичным использованием цикла do/while является процедура выбора пунктов меню. Когда набран корректный ответ, она возвращает значение функции. Неправильный ответ приводит к повторному вводу. Следующий пример являет собой улучшенную версию меню программы проверки орфографии: void menu(void) { char ch; printf("1. Check Spellirig\n"); printf("2. Correct Spelling Errors\n"); printf("3. Display Spelling Errors\n"); printf("    Enter your choice: "); do { ch = getche(); /* чтение клавиатуры */ switch(ch)           { case '1' :      check_spelling ();    break; case '2' :      correct_errors ();    break; case '3' :      display_errors();     break;           }       }       while(ch!='1' && ch!='2' && ch!='3'); } В случае функции меню необходимо выполнить ее, по крайней мере, один раз. После отображения опций программа зацикливается до тех пор, пока не будет осуществлен корректный выбор.

BREAK

Оператор break имеет два назначения. Первое - это окончание работы оператора switch. Второе - это принудительное окончание цикла, минуя стандартную проверку условия. Данное назначение здесь и рассматривается. Когда оператор break встречается в теле цикла, цикл немедленно заканчивается и выполнение программы переходит на строку, следующую за циклом. Например: #include <stdio.h> int main(void) { int t; for(t=0; t<100; t++) { printf ("%d ", t) ; if (t==10) break; } return 0; } Данная программа выводит числа от 0 до 10 включительно и заканчивает работу, поскольку break вызывает немедленный выход из цикла, минуя условие t< 100.

Оператор break, как правило, используется в циклах, где особые условия могут вызвать немедленное завершение работы. Ниже приведен пример того, как нажатие на клавишу может остановить выполнение функции look_up(): int look_up(char *name) { char tname[40]; int loc; loc = -1; do { loc = read_next_name(tname); if(kbhit ()) break; } while(!strcmp(tname, name)); return loc; } Можно использовать функции такого типа для поиска имени в файле базы данных. Если файл слишком длинный и надоело ждать, то можно нажать на клавишу и выйти из функции до окончания работы. Функция kbhit() возвращает 0, если не было нажатия. В противоположном случае она возвращает ненулевое значение, break вызывает выход из самого внутреннего цикла. Например: for(t=0; t<100; ++t) { count = 1; for(;;) { printf ("%d ", count); count++; if (count == 10) break; } } выводит числа от 1 до 10 включительно 100 раз. Каждый раз, когда встречается break, контроль передается внешнему циклу for.

break, используемый в операторе switch, влияет только на данный switch, но не на цикл, в котором может находиться switch.

EXIT()

Функция exit(), находящаяся в стандартной библиотеке, вызывает немедленное окончание работы программы. Поскольку функция exit() останавливает выполнение программы и форсирует возврат в операционную систему, она используется для управления устройствами, и ее использует подавляющее большинство программ. Функция exit() имеет следующий вид: void exit (int статус); Она использует заголовочный файл stdlib.h. Значение статуса возвращается в операционную систему.

Для индикации корректности завершения работы exit() традиционно вызывается с аргументом 0.

Другие аргументы используются для индикации различного рода ошибок. Можно также использовать предопределенные макросы EXIT_SUCCESS и EXIT_FAILURE в качестве значений для статуса.

exit() используется, когда условия выполнения программы неудовлетворительны. Например компьютерная игра может требовать специальный графический адаптер. Функция main() данной игры может выглядеть следующим образом: #include <stdlib.h> int main(void) { if (!special_adaptor()) exit(1); play (); return 0; } где special_adaptor() - это определенная пользователем функция, возвращающая истину, если необходимый адаптер присутствует. Если карта в системе отсутствует, то данная функция возвращает ложь и программа завершает работу.

В другом примере exit() используется для выхода из программы и возврата в операционную систему void menu(void) { char ch; printf ("1.    Check Spelling\n"); printf ("2.    Correct Spelling, Errors\n"); printf("3.    Display Spelling Errors\n"); printf("4.    Quit\n"); printf("    Enter your choice: "); 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. Но вместо форсированного окончания continue переходит к следующей итерации цикла, пропуская оставшийся код цикла. Например, следующая процедура выводит только положительные числа: do { scanf("%d", &x); if(x<0) continue; printf("%d ", x); } while(x!=100);

В циклах while и do/while оператор continue вызывает переход к проверке условия и затем продолжает работу цикла. В случае for выполняется часть увеличения, затем проверяется условие и, наконец, выполняется само тело цикла. Предыдущий пример может быть изменен для вывода только 100 чисел следующим образом: for(t=0; t<100; ++t) { scanf ("%d", &x); if (x<0) continue; printf ("%d ", x); }

В следующем примере оператор continue используется для ускорения выхода из цикла путем форсирования проверки, выполненной ранее: void code(void) { char done, ch; done = 0; while (!done) { ch = getchar(); if (ch == '.') { done = 1; continue; } putchar(ch+1); /* сдвиг алфавита на одну позицию */ } } Можно использовать данную функцию для кодирования сообщений, сдвигая все символы на 1 вверх, то есть 'a' станет 'b'. Функция завершает работу при обнаружении точки, и вывода на экран символа, соответствующего точке, не происходит, поскольку благодаря continue выполнение, минуя оператор вывода, переходит к условию проверки, которое обнаруживает, что done истинно, и вызывает выход.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]