В языке C составная инструкция употребляется в тех случаях, когда по правилам языка требуется одна инструкция, а по логике программы необходимо несколько.
Формат:
{<инструкция>;[<инструкция>;]...}
Пример. Найти x=max(a, b), y=min(a, b).
if(a>b){
x=a; y=b;
}else{
x=b; y=a;
}
В языке Basic такой инструкции нет по той же причине, что и пустой инструкции.
5.6. Циклы
Циклические (повторяющиеся) фрагменты программы можно реализовать с помощью уже рассмотренных инструкций, однако это делает фрагменты более длинными и ухудшает читабельность текста. Тем не менее умение запрограммировать циклы с помощью этих инструкций весьма полезно, поскольку проясняет последовательность действий при выполнении инструкций цикла.
Обобщенная блок-схема цикла состоит из следующих блоков (см. раздел 1.3): задание начальных значений, проверка условия продолжения (окончания) цикла, тело цикла, изменение условия продолжения (окончания) цикла.
Примеры. Программирование циклов без использования инструкции цикла.
Дано: {ai}, i=1...100. Найти сумму(ai>0) и сумму(ai<0).
Она отличается тем, что цикл повторяется до тех пор, пока условие не примет значение True. Выбор разновидности определяется тем, какое условие(продолжения или прекращения цикла) легче сформулировать или короче записать.
Пример.
s=0 : u=1 : n=1
Do Until Abs(u)<=5e-6
u *= x/n : s += u : n += 1
Loop
Есть еще 1 инструкция, более похожая на инструкцию языка C:
While <условие>
<инструкции>
End While
Работает так же, как инструкция Do While ... Loop.
Рекомендация. Циклы while разумно применять в тех случаях, когда:
- число повторений тела цикла не определено;
- неизвестна закономерность повторений или она сложна.
Замечание. Заметим, что один и тот же алгоритм может быть реализован с любым видом инструкции цикла и даже, вообще, без них. В вопросе выбора вида инструкции надо руководствоваться понятностьютекста программы, прежде всего, для себя, а также для других возможных читателей.
1. Каждое из выражений является необязательным. Влияние отсутствия любого из них на выполнение, удобно проследить по эквивалентной схеме.
2. Тело цикла – одна инструкция, которая может отсутствовать.
Примеры.
Дано: {ai}, i=1...100. Найти сумму(ai>0) и сумму(ai<0).
u=v=0;
for(i=0; i<100; i++){
if(a[ i ]>0)u+=a[ i ]; if(a[ i ]<0)v+=a[ i ];
}
Найти Σxn/n!,n=1,2,..., пока |un|>5e-6.
s=0;u=1;
for(n=1; fabs(u)>5e-6; n++){
u *= x/n; s += u;
}
Определить число цифр натурального числа n.
for(k=0; n!=0; n/=10)k++;
Найти первый отрицательный элемент массива. Если его нет, то ответ должен быть равным 0.
for(i=0; i<100 && a[ i ]>=0; i++); // Тело цикла отсутствует
if(i==100){
y=0;
}else{
y=a[ i ];
}
Замечания.
1. Как видно из примеров, почти все циклы используют для своей организации некоторую переменную, которую называют параметром или счетчиком цикла. См. переменные i, n, k, i в порядке следования примеров. Эту переменную не рекомендуется изменять в теле цикла, поскольку логика алгоритма становится запутанной.
2. После окончания цикла параметр сохраняет последнее присвоенное значение. В последнем примере i равно 100, если отрицательных элементов в массиве нет, или равно первому по порядку следования в массиве отрицательному элементу.
3. Это наиболее универсальная форма инструкции цикла.
Basic
Используется более простая форма инструкции for, которую иногда называют циклом типа арифметической прогрессии.
2. Если опция (часть инструкции) Step отсутствует, то шаг равен 1.
3. Отсутствие <счетчика> в инструкции Next не влияет на работу цикла, являясь, по существу, дополнительным комментарием, особенно при вложенных циклах, о которых речь пойдет ниже.
4. Значение <счетчика> после окончания цикла равно последнему присвоенному значению (как в языке C).
5. Значения <начало>, <шаг> и <конец> вычисляются 1 раз при входе в цикл. Изменение переменных, входящих в эти выражения, в инструкциях тела цикла не влияют на число повторений, поэтому так действовать не следует.
Пример. Дано: {ai}, i=1...100. Найти сумму(ai>0) и сумму(ai<0).
u=0 : v=0
For i=1 To 100
If a(i)>0 Then u += a[i] : If a(i)<0 Then v += a(i);
Используются существенно реже, потому что основное отличие их от предыдущих инструкций заключается в том, что в них тело цикла в первый раз выполняется без проверки условия продолжения (прекращения) цикла. Единственный смысл применения такой конструкции, на наш взгляд, состоит в получении в теле цикла с помощью операций ввода-вывода информации из внешней среды, которая используется в условии. Заметим, что подобная манипуляция легко реализуется с помощью циклов с предусловием заданием условия, которое при первом проходе по циклу заведомо выполняется. Тем не менее рассмотрим инструкции, реализующие такие циклы.
C
Формат:
do <инструкция> while <условие>;
Эквивалентная схема:
label: <инструкция>;
if(<условие>)goto label;
Пример. Дано: {ai}, i=1...100. Найти Σai и Πai.
s=i=0;
p=1;
do {
s += a[ i ]; p *= a[ i ]; i++;
} while(i<100);
Basic
Формат:
Do
<инструкции>
Loop {While | Until} <условие>
Пример. Тот же.
s=0 : i=0 : p=1
Do
s += a( i ) : p *= a( i ) : i += 1
Loop While i<100
5.6.3. Вложенные циклы
Суть: инструкция тела цикла есть другая инструкция цикла.
for(x=2; x<3.05; x+=.1){// Формирование массива значений
j++;
p[ j ]=0; // Вычисление значения полинома для заданного x
for(i=n; i>=0; i--){
p[ j ]=p[ j ]*x+a[ i ];
}
}
Ограничение x 3.05 выбрано из-за возможных ошибок округления дробного значения параметра. Цикл при x=3 выполнится, при x – нет. При ограничении 3.0 нет гарантии выполнения цикла при x=3.
Basic
j=-1
For x=2 To 3.05 Step 0.1 ' Формирование массива значений
j=j+1
p( j )=0 ‘ Вычисление значения полинома для заданного x
For i=n To 0 Step -1
p( j )=p( j )*x+a( i )
Next i
Next x 4. Дана матрица {aik}, i,k=1...10. Найти {bi}, i=1...10, где
1, если в i-й строке диагональный элемент максимален