Формат оператора следующий:
do
оператор
while (логическое выражение);
Сначала выполняется образующий тело цикла оператор (простой или составной), а затем вычисляется логическое выражение. Если выражение принимает значение ИСТИНА, тело цикла выполняется еще раз и проверка повторяется. Цикл завершается, когда выражение примет значение ЛОЖЬ.
Этот вид цикла применяется в тех случаях, когда тело цикла необходимо обязательно выполнить хотя бы один раз, например, если в цикле вводятся данные и выполняется их проверка. В остальных случаях предпочтительнее пользоваться циклом с предусловием. Рассмотрим предыдущий пример, в котором теперь используем цикл с постусловием:
#include <stdio.h>
void main()
{
int number, half, div;
scanf(“%d”, &number);
half = number/2;
div =2;
do
{
If(number % div == 0)
printf(“%d ”, div);
div++;
}
while(div <= half);
}
Однако эта программа будет работать неправильно в случае поиска делителей для числа 2.
Цикл с параметром for
Формат оператора следующий:
for (инициализация; логическое выражение; модификация)
оператор
Инициализация служит для присвоения начальных значений величинам, используемым в цикле. В этой части допускается записывать несколько операторов присваивания, разделенных запятой. Инициализация выполняется один раз в самом начале исполнения цикла.
Логическое выражение определяет условие продолжения цикла: если его значение есть ИСТИНА, выполняется образующий тело цикла оператор (простой или составной), иначе происходит завершение работы цикла. Цикл с параметром реализован как цикл с предусловием.
Модификация выполняется после каждой итерации цикла и служит обычно для изменения параметра цикла. В части модификации допускается записывать несколько операторов через запятую.
Снова вернемся к рассмотрению предыдущего примера (найти все делители целого положительного числа), в котором теперь используем цикл for:
#include <stdio.h>
void main()
{
int number, half, div;
scanf (“%d”, &number);
half = number/2;
for (div =2; div <= half; div++)
if (number % div == 0)
printf(“%d ”, div);
}
В операторах цикла могут использоваться операторы break и continue. Оператор break вызывает немедленный выход из цикла. Оператор continue осуществляет немедленный переход к следующей итерации цикла.
Пример, иллюстрирующий использование оператора break: суммировать числа, вводимые с клавиатуры до тех пор, пока не будет введено число 0, после чего вывести полученную сумму на экран.
#include <stdio.h>
void main()
{
int num, sum = 0;
while (1) //запускается бесконечный цикл
{
scanf(“%d”, &num);
if (num == 0) break;
sum += num;
}
printf(“Сумма = %d”, sum);
}
Пример фрагмента кода, иллюстрирующего использование оператора continue для того, чтобы исключить операцию деления на ноль:
#include <stdio.h>
void main()
{
...
for (i = 0; i < N; i++)
{
if (i == k) continue;
sum += 1.0/(i - k);
}
...
}
Любой цикл while может быть приведен к эквивалентному ему циклу for и наоборот. Например, два следующих цикла эквивалентны:
for (part1; part2; part3) part1;
оператор while (part2)
{
оператор
part3;
}
Отсюда видно, что достоинством цикла for является то, что все управление циклом сосредоточено в его заголовке, что делает программу более простой и понятной.
При необходимости любая из трех частей, содержащихся в заголовке оператора for, может быть опущена, однако точки с запятой надо оставить на своих местах. Например, четыре следующих цикла for эквивалентны:
//1
for (part1; part2; part3)
оператор
//2
part1;
for (; part2; part3)
оператор
//3
for (part1;; part3)
{
if (!part2) break;
оператор
}
//4
for (part1; part2;)
{
оператор
part3;
}
Подобным образом можно опустить любые две из трех частей, содержащихся в заголовке оператора for, или даже все 3 части, получая следующее:
part1;
for (;;) //запускается бесконечный цикл
{
if (!part2) break;
оператор
part3;
}
Если тело цикла невелико, можно переместить его в заголовок по правилам операции «запятая». После заголовка необходимо поставить пустой оператор (;):
for (part1; part2; оператор, part3);
Циклы можно вкладывать друг в друга. При этом в качестве параметров вложенных циклов должны быть использованы различные переменные. Пример вывода на экран школьной таблицы умножения:
#include <stdio.h>
void main()
{
const int N = 9;
int i, j;
for (i = 1; i <= N; i++)
{
for (j = 1; j <= N; j++)
printf(“%3d”, i*j);
printf(“\n”);
}
}
Тема 6. Массивы
Массив – это именованная совокупность переменных одного типа, хранящихся в смежных ячейках оперативной памяти. Переменные, входящие в состав массива, называются его элементами, они имеют одно и то же имя, но различаются своими порядковыми номерами (индексами). Индексы массива всегда начинаются с нуля.
В программе описание массива отличается от описания обычной переменной лишь наличием после имени квадратных скобок, в которых указывается количество элементов массива (размерность массива):
float x[10]; //описание массива х из 10 вещественных чисел
int a[5] = {1, 3, 5, 7, 9}; //описание массива a с инициализацией его элементов. При этом
// a[0]=1, a[1]=3, a[2]=5, a[3]=7, a[4]=9. Элемента a[5] в массиве нет
Если число инициализаторов совпадает с размерностью массива, то размерность можно не указывать:
int a[ ] = {1, 3, 5, 7, 9};
Если элементов в массиве больше, чем инициализаторов, элементы, для которых значения не указаны, обнуляются:
int b[5] = {3, 2, 1}; // b[0]=3, b[1]=2, b[2]=1, b[3]=b[4]=0
Размерность массива предпочтительнее задавать с помощью именованной константы, т.к. в этом случае для изменения размерности массива достаточно скорректировать значение константы всего лишь в одном месте программы. Например, найдем сумму значений всех элементов массива:
#include <stdio.h>
void main()
{
const int N = 10;
int i, sum, mas[N];
for (i = 0; i < N; i++)
scanf(“%d”, &mas[i]);
for (sum=0, i = 0; i < N; i++)
sum += mas[i];
printf(“Сумма = %d”, sum);
}
Многомерные массивы задаются указанием каждого измерения в квадратных скобках. Например, оператор
int matr[3][5];
задает описание двумерного массива из 3 строк и 5 столбцов. В памяти такой массив располагается в последовательных ячейках построчно, то есть при переходе к следующему элементу быстрее всех изменяется последний индекс. Для доступа к элементу многомерного массива указываются все его индексы, например, matr[i][j] для описанного выше двумерного массива есть обращение к элементу, расположенному на пересечении i -й строки и j -го столбца.
Инициализировать многомерный массив можно двумя способами.
1. Задается общий список элементов в том порядке, в котором элементы располагаются в памяти:
int mas[2][4] = {1, 2, 3, 4, 5, 6, 7, 8};
2. Используется представление в виде массива из массивов, при этом каждый массив заключается в свои фигурные скобки:
int mas[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
В обоих случаях левую размерность можно не указывать.
Эти операторы определяют матрицу со следующими значениями элементов:
1 2 3 4
5 6 7 8
Допустимыми являются также варианты, когда указываются не все инициализаторы. Например, оператор int mas[ ][4] = {{1, 2}, {5}}; определяет следующую матрицу:
1 2 0 0
5 0 0 0
При работе с элементами многомерных массивов обычно используют вложенные циклы, как в следующем примере, где подсчитывается сумма значений всех элементов двумерного массива:
#include <stdio.h>
void main()
{
const int N = 10, M = 5;
int i, j, sum, mas[N][M];
for (i = 0; i < N; i++)
for (j = 0; j < M; j++)
scanf(“%d”, &mas[i][j]);
for (sum=0, i = 0; i < N; i++)
for (j = 0; j < M; j++)
sum += mas[i][j];
printf(“Сумма = %d”, sum);
}