.RU

Командой повторения или циклом называется такая форма организации действий, при которой одна и та же последовательность действий повторяется до тех пор, пока

Вложенные циклы


Командой повторения или циклом называется такая форма организации действий, при которой одна и та же последовательность действий повторяется до тех пор, пока сохраняется значение некоторого логического выражения. При изменении значения логического выражения на противоположное повторения прекращаются (цикл завершается).
Для организации цикла необходимо выполнить следующие действия:
1 перед началом цикла задать начальное значение параметра;
2 внутри цикла изменять параметр цикла с помощью оператора присваивания;
3 проверять условие повторения или окончания цикла;
4 управлять циклом, т.е. переходить к его началу, если он не закончен, или выходить из цикла в противном случае.
Один цикл повторения может находиться внутри другого цикла. При использовании вложенных циклов следует соблюдать простое правило: один цикл внутри другого должен находиться так же, как одна матрешка внутри другой матрешки.
Вложенным называется цикл, находящийся внутри другого цикла.
Рассмотрим пример, в котором вложенные циклы используются для нахождения всех простых чисел, не превышающих данного значения. Простое число - это такое число, которое делится нацело только на 1 и само на себя. Первыми простыми числами будут 2, 3, 5, 7 и 11.
Самый легкий способ узнать, является ли число простым, состоит в делении его на все числа между 1 и им самим. Если оно делится нацело на какое-нибудь число из этого ряда, то оно - не простое. Мы воспользуемся операцией деления по модулю (%) для проверки, выполнялось ли деление нацело. (Вы не забыли еще, конечно, операцию деления по модулю? Ее результатом является остаток от деления первого операнда на второй. Если одно число делится на другое нацело, результатом операции деления по модулю будет 0.) При обнаружении какого-нибудь одного делителя числа дальнейшие проверки потеряют смысл. Поэтому в программе процесс проверки данного числа завершается после того, как найден его делитель.
Начнем с программы, проверяющей делимость одного числа. В ней имеется всего один оператор цикла.
/* простое число1 */
main( )
{
int number, divisor;
printf(" О каком числе вы хотите знать, простое ли оно?\n");
scanf(" %d" , &number); /* получение ответа */
while(number <2) /* число отвергается */
{
printf(" Извините, мы не принимаем чисел меньше 2.\n");
printf(" Пожалуйста, попробуйте еще раз.\n");
scanf(" %d" , &number);
}
for(divisor = 2; number % divisor != 0; divisor++)
; /* проверка, простое число или нет,
осуществляется внутри спецификации цикла */
if (divisor == number) /* выполняется после завершения цикла */
printf(" %d - простое число.\n", number);
else printf(" %d - не простое число.\n", number);
}
Мы воспользовались структурой цикла while, чтобы избежать ввода значений, которые могли бы привести к аварийному завершению программы.
Обратите внимание, что все вычисления выполняются внутри спецификации цикла for. Величина переменной number последовательно делится на возрастающие значения делителей до тех пор, пока не произойдет деление нацело (т. е. number % divisor станет равным 0). Если первым делителем, который приведет к такому результату окажется само это число, то значение переменной number - простое число. В противном случае данное число будет иметь меньший делитель, и это приведет к тому, что цикл завершится раньше.
Для нахождения всех простых чисел, меньших некоторой заданной величины, нам нужно будет заключить наш цикл for в некоторый другой цикл. На псевдокоде это будет выглядеть следующим образом:
для числа (number)=1 до верхнего предела limit проверять, является ли число простым
Вторая строка представляет собой нашу предыдущую программу. Переводя эту запись на язык Си, получим программу:
/* простые числа2 */
main( )
{
int number, divisor, limit;
int count = 0;
printf(" Укажите, пожалуйста, верхний предел для поиска простых чисел.\n");
printf(" Верхний предел должен быть 2 или больше.\n");
scanf(" %d", &limit);
while(limit < 2) /* вторая попытка, если ошибка при вводе */
{
printf(" Вы были не внимательны! Попробуйте еще раз. \n");
scanf(" %d", &limit);}
printf(" Сейчас будут печататься простые числа!\n");
for(number = 2; number <= limit; number++) /* внешний цикл */
{
for(divisor =2; number % divisor != 0; divisor++);
if(divisor == number)
{
printf(" %5d", number);
if(++count % 10 == 0)
printf(" \n"); /* новая строка начинается через каждые 10 простых чисел */
}
}
printf(" \n Р’РѕС‚ Рё РІСЃРµ!\n");
}
Во внешнем цикле каждое число, начиная с 2 и кончая величиной limit, последовательно берется для проверки. Указанная проверка осуществляется во внутреннем цикле. Мы использовали переменную count для хранения счетчика получаемых простых чисел. При печати каждое одиннадцатое простое число мы начинаем с новой строки. Ниже приводится пример результатов, получаемых с помощью такой программы:
Укажите, пожалуйста, верхний предел для поиска простых чисел. Верхний предел должен быть 2 или больше.
250
Сейчас будут печататься простые числа!
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229 233 239 241
Р’РѕС‚ Рё РІСЃРµ!
Этот способ решения довольно прост, но он не является самым эффективным. Например, если вы хотите узнать, является ли число 121 простым или нет, нет необходимости проверять, существуют ли у него делители, превышающие 11. Дело в том, что если у данного числа существует делитель, больший 11, то результатом деления будет число, меньшее 11; тогда этот делитель был бы обнаружен раньше. Поэтому требуется проверять только делители, не превышающие величину квадратного корня из числа, но в данном случае программа будет несколько сложнее. Мы оставляем ее в качестве упражнения любознательному читателю. (Указание: вместо того чтобы сравнивать делитель с величиной квадратного корня из числа, сравнивайте квадрат делителя с самим числом.)

^ Итерационные процессы и циклы


До сих пор мы рассматривали повторяющиеся (циклические) процессы, в котором действия и результаты одного шага цикла не влияли на последующие шаги. В таких циклах параметры заголовка цикла не зависят от значений переменных, вычисляемых в теле цикла, и цикл имеет постоянное количество повторений, например:
for (i=0; iНо среди циклических процессов имеются и такие, в которых поведение программы на некотором шаге цикла может зависеть от результатов выполнения тела цикла на предыдуших шагах. То же самое можно сказать и о самом числе повторений цикла. Такие процессы и циклы называются ИТЕРАЦИОННЫМИ. Наиболее широко они применяются в вычислительной математике, когда для получения численного результата используется итерационный цикл ПОСЛЕДОВАТЕЛЬНЫХ ПРИБЛИЖЕНИЙ к нему.

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


Если попытаться изобразить общую схему итерационного цикла, то в нем обязательно будут переменные, сохраняющие результат предыдущего (x1) и еще более ранних (x2,...) шагов, а также переменная (x) - результат текущего шага:
+------------- Начальные значения предыдущих шагов
¦ ¦ +--------- Условие завершения цикла
¦ ¦ ¦ +------ Следующий шаг
for (x1=...,x2=...; l(x1,x2); x2=x1,x1=x)
{ ...x = f(x1,x2);...}
Если в итерационном цикле гарантируется выполнение одного шага, тo может быть использован цикл do...while:
x=...; x1=...; ------ Начальное значение текущего шага
do +---------------- Следующий шаг
{ В¦
x2 = x1; x1 = x;
x = f(x1,x2); ----------- Результат текущего шага
} while (l(x2,x1,x));---- Условие завершения
Если использовать результат только текущего шага, который зависит от результата предыдущего, то схему цикла можно упростить:
for (x=...; l(x); ) { ...x = f(x);... }
Пример:^ Нахождение корня функции методом половинного деления
Если имеется математическая функция, значение которой в Си вычисляется некоторой функций вида
double f(double x);
и если математическая функция монотонно возрастает или убывает на заданном интервале (a,b), имея на его концах противоположные знаки, то корень функции x можно найти методом половинного деления интервала. Проще говоря, если кривая на интервале (a,b) пересекает ось X, то к этой точке пересечения можно приблизиться, последовательно уменьшая этот интервал путем его деления пополам.
Сущность алгоритма состоит в проверке значения функции на середине интервала. После проверки из двух половинок выбирается та, на концах которых функция имеет разные знаки. Процесс продолжается до тех пор, пока интервал не сократится до заданных размеров, определяющих точность результата:
//-----Корень функции по методу середины интервала
double f(double); // Объявление функции f()
double find(double a, double b)
{
double c; // Середина интервала
if (f(a)*f(b) >0)
return (0.); // Одинаковые знаки
for (; b-a > 0.001;)
{
c = (a+b) / 2; // Середина интервала
if (f(c)*f(a) >0)
a = c; // Правая половина интервала
else
b = c; // Левая половина интервала
}
return(a); // Возвратить один из концов
} // интервала
В данном примере итерационный характер цикла не очень-то и просматривается. Но положение интервала на новом шаге цикла (правая или левая половина) определяется предыдущим шагом, поэтому итерационность все же присутствует.
Задача: Разработать алгоритм и составить программу вычисления значений суммы S заданного ряда при различных значениях аргумента Х: во внутреннем цикле для фиксированного значения Х поочередно суммировать члены ряда, пока их абсолютная величина превышает заданную точность eps. Вычисление очередного член ряда осуществлять по рекуррентной формуле. Во внешнем цикле аргумент Х изменяется от 0,5 до 0,75 с шагом 0,05.

Вычисление значения суммы S и значения выражения Y оформить в виде функций.
double iter (double x, double e, double obs)
{
double q;
double first = x/6;
q=first;
while ( obs > e)
{
q = q*obs;
}
return q;
}
int main()
{
double e,a,obs;
cout<<"vvedite pogresnost E: ";
cin>>e;
while ( e <= 0 )
{
cout < 0: ";
cin>>e;
}
cout<< "X kontrol symma" << endl;
int n;
for ( double x=0.5; x<=0.75; x+=0.05)
{
a=x*x;
n=0;
obs = (-1 * a) / ((2*n+2)*(2*n+3));
cout<cout<<" " << control(a,x);
cout<<" " << iter(x,e,obs)<n+=1;
}
getch();
}

Задача 1:

Получить на компьютере таблицу умножения натуральных чисел.
Программа для решения данной задачи представлена ниже.
#include
#include
#include
main()
{
char str[50];
int i,j; // счетчики циклов: внешнего и внутреннего
// Очистить экран
textbackground(4);
textcolor(15);
clrscr();
// Внешний цикл
for(i=1;i<10;i++)
{
// Внутренний цикл
for(j=1;j<5;j++)
{
printf("%d * %d = %d", i, j, i*j);
printf("\n");
}
printf("\n");
}
CharToOem("\nДля выхода нажмите любую клавишу", str);
printf(str);
getch();
}
Хочу обратить Ваше внимание на структуру внешнего и внутреннего циклов в языке Си. Вы видите, что для внешнего цикла выбран счетчик i. Аналогично, счетчик j служит для организации внутреннего цикла. Каждый цикл: внешний или внутренний имеют в своем начале команду: for(i=1;i<10;i++) или for(j=1;j<5;j++). Далее цикл поле этой команды может иметь как одну, так и несколько команд. Если имеется несколько команд в цикле, то цикл обязательно заключается в фигурные: {...} скобки. Это правило относится в равной степени как к внешнему, так и к внутреннему циклам. В противном случае, если цикл содержит всего только одну команду, фигурные скобки не проставляются!
Аналогично, можно включить в каждую группу не 4, а 10 строк и взять не 9, а 10 групп. Для этого необходимо немного переделать программу. А именно, изменить команды организации внешнего и внутреннего циклов: for(i=1;i<=10;i++) и for(j=1;j<=10;j++).
Задача 2
Получить на компьютере квадрат Пифагора - таблицу умножения натуральных чисел.
Таблица показана ниже на рисунке.
1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 2 4 6 8 10 12 14 16 18 20
3 3 6 9 12 15 18 21 24 27 30
4 4 8 12 16 20 24 28 32 36 40
5 5 10 15 20 25 30 35 40 45 50
6 6 12 18 24 30 36 42 48 54 60
7 7 14 21 28 35 42 49 56 63 70
8 8 16 24 32 40 48 56 64 72 80
9 9 18 27 36 45 54 63 72 81 90
10 10 20 30 40 50 60 70 80 90 100
Программу написать в языке Си.
Вы видите, что здесь в таблице всего 10 строк. Самая верхняя строка содержит числа, которые умножаются на числа из самого крайнего левого столбца. В этом столбце всего 9 строк. Причем на пересечении строки из крайнего левого столбца со столбцом из верхней строки находятся произведения соответствующих чисел, записанных в левом столбце и в верхней строке.
Можно предположить, что внешний цикл это цикл по крайнему левому столбцу. Тогда внутренний цикл это цикл по самой верхней строке. В крайнем левом столбце числа изменяются от 1 до 9. Поэтому соответствующая команда для организации внешнего цикла будет иметь вид:for(i=1;i<=10;i++). В то же время ей будет соответствовать следующая команда для внутреннего цикла: for(j=1;j<=10;j++).
Программа для решения данной задачи предствлена ниже. Здесь, как и на прошлом уроке, разными цветами раскрашены важные части программы. Сделано это для большей наглядности и лучшего восприятия отдельных частей программы.
// Квадрат Пифагора - таблица умножения
#include
#include
#include
void main()
{
char str[50];
int i,j; // счетчики циклов: номер строки и номер столбца
// Очистить экран
clrscr();
textbackground(4);
textcolor(15);
// запись чисел верхней строки
printf(" ");
// левая верхняя клетка таблицы
for(j=1;j<=10;j++) // первая строка
printf("%4i", j); // содержит номера столбцов
printf("\n");
{
// внешний цикл
for(i=1;i<=10;i++)
{
printf("%4i", i); // номер строки
// внутренний цикл
for(j=1;j<=10;j++) // строка таблицы
printf("%4i", i*j);
printf("\n");
}
CharToOem("\nДля выхода нажмите любую клавишу", str);
printf(str);
getch();
}
2010-07-19 18:44 Читать похожую статью
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • Контрольная работа
  • © Помощь студентам
    Образовательные документы для студентов.