Циклические конструкции в программах — КиберПедия 

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Циклические конструкции в программах

2017-07-01 301
Циклические конструкции в программах 0.00 из 5.00 0 оценок
Заказать работу

 

Наряду с операторами (или группами операторов), которые могут выполняться в зависимости от каких-либо условий, существуют еще и операторы, которые могут выполняться несколько раз в одной и той же последовательности. Такой вид конструкции в программе известен как цикл. Существуют три основных типа циклов (хотя два из них можно рассматривать как разновидность одного). Это цикл while (“ пока ”), цикл for (“ для ”) и цикл do...while (“ делать...пока ”). Рассмотрим их по порядку.

 

4.7.1. Цикл while

 

Цикл while является наиболее общим и может использоваться вместо двух других типов циклических конструкций. В принципе можно сказать, что по-настоящему для программирования необходим только цикл while, а другие типы циклических конструкций служат лишь для удобства написания программ.

 

Загрузите с диска файл HELLO.CPP и измените его следующим образом:

 

#include <stdio.h>

void main ()

{

char ch;

int len;

len=0;

puts("Наберите предложение, затем нажмите

<Enter>");

while((ch=getch())!= ‘\n’)

{

putch (ch);

len++;

}

printf("\nВаше предложение имеет длину %d символов

\n", len);

}

 

Эта программа позволяет ввести предложение с клавиатуры и подсчитать при этом, сколько раз вы нажали на клавиши клавиатуры до тех пор, пока не нажали на клавишу <Enter> (соответствует специальному символу конца строки – ‘ \n ’). Затем программа сообщит вам сколько символов (символ ‘ \n ’ не подсчитывается) вы ввели. Для отображения вводимых символов на экране используется функция putch.

Заметьте, что в условном выражении оператора while используется выражение присваивания. Это позволяет программе читать и одновременно сравнивать считанные символы с символом, соответствующим клавише <Enter>. Если считанный символ не <Enter>, то программа отображает его на экране дисплея и увеличивает на единицу значение len.

Оператор while имеет следующий формат:

 

while (выражение)

оператор;

 

где “ выражение ” принимает нулевое или отличное от нуля значение, а “ оператор ” может представлять собой как один оператор, так и группу операторов.

В процессе выполнения цикла while вычисляется значение “ выражения ”. Если оно истинно, то “ оператор ”, следующий за ключевым словом while, выполняется и “ выражение ” вычисляется снова. Если “ выражение ” ложно, то цикл while завершается и программа продолжает выполняться дальше. Обратите внимание на другой пример цикла while:

 

void main()

{

char *msg;

int indx;

msg = "Здравствуй, мир";

indx = 1;

while(indx <= 10)

{

printf("Время # %2d: %s\n", indx, msg);

indx++;

}

}

 

После компиляции и выполнения этой программы на экране будут отображены строки со следующей информацией:

 

Время # 1: Здравствуй, мир

Время # 2: Здравствуй, мир

Время # 3: Здравствуй, мир

...............................................

Время # 9: Здравствуй, мир

Время # 10: Здравствуй, мир

 

Очевидно, что оператор printf был выполнен ровно десять раз, при этом значение параметра цикла indx изменилось от 1 до 10.

Немного подумав, вы сможете переписать этот цикл несколько компактнее:

 

indx = 0;

while(indx++ < 10)

printf("Время #%2d: %s\n", indx, msg);

 

Изучайте этот второй пример цикла while до тех пор, пока вам не станет ясно, почему он работает точно так же, как и в первом случае. Затем переходите к изучению цикла типа for.

 

4.7.2. Цикл for

 

Цикл for является одним из основных видов циклов, которые имеются во всех универсальных языках программирования, включая С++. Однако, версия цикла for, используемая в С++, как вы увидите, обладает большей мощностью и гибкостью.

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

 

void main ();

{

char *msg;

int indx;

msg = "Здравствуй, мир";

for(indx = 1; indx <= 10; indx++)

printf("Время #%2d: %s\n", indx, msg);

}

 

Выполните эту программу и вы убедитесь, что она делает те же действия, что и программа с циклом while, которую мы уже разобрали, и является точным эквивалентом первого ее варианта.

Теперь приведем основной формат цикла for:

 

for (выр1; выр2; выр3)

оператор;

 

Так же, как и в цикле while, “ оператор ” в теле цикла for обычно является одним из операторов программы, но может использоваться и составной оператор, заключенный в фигурные скобки ({...}).

Заметим, что параметры цикла for, заключенные в скобки, должны разделяться точкой с запятой (позиционный параметр), которая делит, в свою очередь, пространство внутри скобок на три сектора. Каждый параметр, занимающий определенную позицию, означает следующее:

выр1 – обычно задает начальное значение индексной переменной;

выр2 – условие продолжения цикла;

выр3 – обычно задает некоторую модификацию (приращение) индексной переменной за каждое выполнение цикла.

Основной вариант цикла for эквивалентен следующей конструкции, выраженной с помощью цикла while:

 

выр1;

while (выр2)

{

оператор;

выр3;

}

 

Вы можете опускать одно, несколько или даже все выражения в операторе for, однако о необходимости наличия точек с запятой вы должны помнить всегда. Если вы опустите “ выр2 ”, то это будет равносильно тому, что значение выражения “ выр2 ” всегда будет иметь значение 1 (истина) и цикл никогда не завершится (такие циклы известны еще как бесконечные).

Во многих случаях вам поможет использование оператора запятая (,), который позволяет вводить составные выражения в оператор цикла for. Вот, например, еще одна правильная модификация файла HELLO.CPP с использованием составного выражения в операторе for:

 

void main();

{

char *msg;

int up, down;

msg = "Здравствуй, мир";

for(up = 1, down = 9; up <=10; up++, down--)

printf("%s: %2d растет, %2d уменьшается \n",

msg, up, down);

}

 

Заметьте, что и первое, и последнее выражение в этом цикле for состоят из двух выражений, инициализирующих и модифицирующих переменные up и down. Вы можете сделать эти выражения сколь угодно сложными.

 

4.7.3. Цикл do... while

 

Последним видом цикла является цикл do... while. Модифицируйте RATIO.CPP следующим образом:

 

void main()

{

float a, b, ratio;

char ch;

do

{

printf("Введите два числа: ");

scanf("%f %f", &a, &b);

if(b == 0.0)

printf("\nВнимание! Деление на ноль! ");

else

{

ratio = a/b;

printf("\nРезультат деления двух чисел: %f",

ratio);

}

printf("\nНажми ‘q’ для выхода или любую клавишу

для продолжения")

}

while((ch = getch())!= ‘q’);

}

 

Эта программа вычисляет результат деления одного числа на другое. Оба числа вводятся по запросу программы с клавиатуры. Если вы введете символ q, то выражение в операторе цикла while в конце программы примет значение ”ложь” и цикл (а значит и программа) завершится. Если вы введете какой-либо другой символ, отличный от q, то выражение будет иметь значение “истина” и цикл повторится.

Формат цикла do... while можно представить в виде:

 

do оператор while (выр);

 

Основным отличием между циклом while и циклом do... while в том, что операторы внутри do... while всегда выполняются хотя бы один раз (т.к. проверка условия выполнения цикла осуществляется после выполнения последовательности операторов составляющих тело цикла). Это похоже на цикл repeat... until в Паскале с одним, однако, различием: цикл repeat выполняется до тех пор (until), пока его условие станет истинно; а цикл do... while выполняется пока (while) его условие истинно.

 

4.7.4. Оператор switch (переключатель)

 

Часто бывает необходимо построить длинные конструкции типа

 

*done = 0;

do

{

cmd = toupper (getch());

if (cmd == ‘F’) do_file_menu(done);

else if (cmd == ‘R’) run_program();

else if (cmd == ‘C’) do_compile();

else if (cmd == ‘M’) do_make();

else if (cmd == ‘?’) do_project_menu();

else if (cmd == ‘O’) do_option_menu();

else if (cmd == ‘E’) do_error_menu();

else handle_others(cmd, done);

}

while (!*done);

 

Подобная ситуация встречается настолько часто, что в С++ была введена специальная управляющая структура которая носит название оператор switch. Вот та же функция, но записанная с использованием оператора switch:

 

#include <ctype.h>

do_main_menu (short *done)

{

char cmd;

*done = 0;

do

{

cmd = toupper (getch());

switch(cmd)

{

case ‘F’: do_file_menu(done); break;

case ‘R’: run_program(); break;

case ‘C’: do_compile(); break;

case ‘M’: do_make(); break;

case ‘?’: do_project_menu(); break;

case ‘O’: do_option_menu(); break;

case ‘E’: do_error_menu(); break;

default: handle_others(cmd, done);

}

}

while (!*done);

}

 

Эта функция организует цикл, в котором символ считывается, преобразуется к значению на верхнем регистре, а затем запоминается в переменной cmd. Потом введенный символ обрабатывается оператором switch на основе значений cmd.

Цикл повторяется до тех пор, пока переменная done не станет равной нулю (предположительно в функции do_file_menu или handle_others).

Оператор switch получает значение cmd и сравнивает его с каждым значением метки case. Если они совпадают, начинается выполнение операторов данной метки, которое продолжается либо до ближайшего оператора break, либо до конца оператора switch. Если ни одна из меток не совпадает, и вы включили метку default в оператор switch, то будут выполняться операторы этой метки; если метки default нет, оператор switch целиком игнорируется.

Значение value, используемое в switch (value) должно быть приведено к целому значению. Другими словами, это значение должно легко преобразовываться в целое для таких типов данных как char, разновидности enum и, конечно, int, а также всех его вариантов. Нельзя использовать в операторе switch вещественные типы данных (такие как float и double), указатели, строки и другие структуры данных, но разрешается использовать элементы структур данных совместимых с целыми значениями.

Хотя (value) может быть выражением (константа, переменная, вызов функции, и другие комбинации их), метки case должны содержать константы. Кроме того, в качестве ключевого значения case может быть только одно значение. Если бы do_main_menu не использовало функцию toupper для преобразования cmd, оператор switch мог бы выглядеть следующим образом:

 

switch (cmd)

{

case ‘f’:

case ‘F’: do_file_menu(done);

break;

case ‘r’:

case ‘R’: run_program();

break;

}

 

Этот оператор выполняет функцию do_file_menu независимо от того, в каком регистре поступает значение cmd, аналогично выполняются действия для других альтернатив значения cmd.

Запомните, что для завершения данного case вы должны использовать оператор break. В противном случае будут выполняться последовательно все операторы, относящиеся к другим меткам (до тех пор пока не встретится оператор break).

Если вы уберете оператор break после вызова do_file_menu, то при вводе символа F будет вызываться do_file_menu, а затем будет вызвана функция run_program.

Однако иногда вам нужно сделать именно так. Рассмотрим следующий пример:

 

typedef enum(sun, mon, tues, web, thur, fri, sat,

sun) days;

void main();

{

days today;

swith (today)

{

case mon:

case tues:

case web:

case thur:

case fri: puts ("Иди работать!"); break;

case sat: printf("Убери во дворе и ");

case sun: puts (“Расслабься!”);

}

}

 

В этом операторе switch для значений от mon до fri выполняется одна и та же функция puts, после которой оператор break указывает на выход из switch. Однако, если today равно sat, выполняется соответствующая функция printf, а затем выполняется puts (“Расслабься”);, если же today равно sun, выполняется только последняя функция puts.

 

Пропуск break. Как вы помните, оператор break используется в операторе switch в конце каждой помеченной альтернативы выбора. Пожалуйста, не забывайте это. Если вы забудете поставить break в данную помеченную альтернативу выбора, то операторы следующих за ней помеченных альтернатив выбора будут также выполняться.

4.7.5. Оператор break

 

Иногда бывает необходимо выйти из цикла до его завершения. Рассмотрим следующую программу:

 

#define LIMIT 100

#define MAX 10

void main()

{

int i, j, k, score;

int scores[LIMIT][MAX];

for (i=0; i < LIMIT; i++)

{

j = 0;

while (j < MAX-1)

{

printf("Введите следующее значение #%d: ", j);

scanf("%d", score);

if (score < 0)

break;

scores[i][++j] = score;

}

scores[i][0] = j;

}

}

 

Рассмотрим оператор if (score < 0) break;. Он указывает, что если пользователь введет отрицательное значение score, цикл while прерывается. Переменная j используется и в качестве индекса scores и в качестве счетчика общего количества элементов в каждой строке; это значение записывается в первом элементе строки.

Вспомните, пожалуйста, использование оператора break в операторе switch, представленное ранее. Там break указывает программе выйти из оператора switch; здесь он указывает программе выйти из цикла и продолжить работу. Кроме оператора switch оператор break может быть использован во всех трех циклах (for, while и do... while), однако его нельзя использовать в конструкции if... else или в теле главной процедуры main для выхода из нее.

 

4.7.6. Оператор continue

Иногда нужно не выходить из цикла, а пропустить ряд операторов в теле цикла и начать его заново. В этом случае можно применить оператор continue, предназначенный специально для этого. Обратите внимание на следующую программу:

 

#define LIMIT 100

#define MAX 10

void main()

{

int i, j, k, score;

int score[LIMIT][MAX];

for (i =0; i < LIMIT; i++)

{

j = 0;

while (j < MAX - 1)

{

printf("Введите следующее значение #%d: ",j);

scanf("%d", score);

if (score < 0)

continue;

scores[i][++j] = score;

}

scores[i][0] = j;

}

}

 

Когда выполняется оператор continue, программа пропускает остаток цикла и начинает цикл сначала. В результате эта программа работает иначе, чем предыдущая. При вводе пользователем числа –1 считается что была сделана ошибка, и вместо выхода из внутреннего цикла цикл while начинается сначала. Поскольку значение j не было увеличено, программа снова просит ввести то же значение.

 

4.7.7. Оператор goto

 

Да, в С++ действительно есть оператор goto. Формат простой:

 

goto метка;

 

где “ метка ” – любой идентификатор, связанный с определенным выражением.

Однако наиболее разумное решение при программировании на С++ – обойтись без использования оператора goto. Для этого предусмотрено три оператора цикла. Подумайте внимательно, прежде чем использовать оператор goto, действительно ли он вам нужен в создавшейся ситуации и может быть его можно заменить на оператор цикла?.

 


Поделиться с друзьями:

Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...

Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.091 с.