Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 - Лекция4_Циклы.docx
Скачиваний:
7
Добавлен:
16.11.2019
Размер:
59.55 Кб
Скачать

Цикл while

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

while (<условие работы>) {

<тело цикла>;

}

Для иллюстрации работы цикла while рассмотрим следующую задачу. Предположим, что кому-то нужно накопить 300 000 рублей на покупку машины, и он периодически кладет деньги в копилку; когда будет накоплено 300 000 рублей или больше, «говорящая» копилка должна сообщить, что денег на покупку достаточно. Описанную ситуацию моделирует код, использующий цикл while:

//Цена автомобиля

const float price = 300000;

printf("Машина стоит %g рублей.\n", price);

//Накопленная сумма

float total = 0;

//Принимем деньги, пока их меньше 300000

while (total < price) {

printf("\nВ копилке %g рублей.\n", total);

printf("Сколько еще положить?\n");

float money;

scanf("%f", &money);

total += money;

}

//Требуемая сумма накоплена

printf("\nВ копилке %g рублей\n",total);

printf("Вы накопили на машину.\n");

Работа программы «Копилка» выглядит так:

Цикл do-while

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

Рассмотрим усовершенствование игры «Угадай число!», разработанной на предыдущем занятии. Напомним, что компьютер не предлагал попробовать еще раз, если с первого раза число не было угадано. Для решения этой проблемы можно поместить игру внутрь цикла, который работает до тех пор, пока число не будет угадано; поскольку первая попытка должна быть произведена в любом случае, то уместно использовать именно do-while.

srand(time(0));

int number = rand() % 10;

int your_number;

//Счетчик количества попыток

int trials = 0;

printf("Угадай число:\n");

do {

trials++;

scanf("%d",&your_number);

if (number != your_number) {

printf("Не угадали!\n\n");

printf("Попробуйте еще раз:\n");

}

} while (number != your_number);

printf("Вы угадали с %d попыток\n", trials);

Программа работает до тех пор, пока условие работы цикла number!=your_number истинно, т.е. введенное число не совпадет с загаданным.

Обработка данных в циклах

Циклические конструкции – это очень мощный инструмент, который предназначен не просто для повторения какого-то действия заданное число раз. Существует масса алгоритмов, созданных для обработки большого количества данных, причем, алгоритмы эти могут быть как элементарными, так и довольно изощренными. Начнем с алгоритма, который встречается повсюду: вычисление суммы элементов какой-то последовательности. Рассмотрим самый простой случай:

1 + 2 + 3 + … + (N-1) + N.

Конечно, человек, знакомый со школьным курсом математики, знает понятие арифметической прогрессии и быстро вычислит сумму по формуле

1 + 2 + 3 + … + (N-1) + N = N*(N+1)/2.

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

Итак, для подсчета требуемой суммы нужно объявить переменную (назовем ее sum) и инициализировать ее нулем, а затем на каждой итерации цикла прибавлять очередной элемент к этой переменной. После обработки всей последовательности переменная sum будет равна сумме всех элементов. Например, при N=7 переменная sum последовательно примет следующие значения: 0, 1, 3, 6, 10, 15, 21 и 28. Последнее значение, равное 28, является суммой чисел от 1 до 7.

int N;

printf("Введите число N:\n");

scanf("%d", &N);

int sum = 0;

for (int i=1; i<=N; i++) {

//Напомним, что эта запись

//эквивалентна sum = sum+i;

sum += i;

}

printf("Сумма чисел от 1 до %d\n", N);

printf("равна %d\n", sum);

Подумайте теперь, как вычислить другую сумму:

1 + 1/2 + 1/3 + … + 1/(N-1) + 1/N.

На первый взгляд, сложностей нет никаких, и нужно просто изменить тип переменной sum на float, заменить выражение sum+=i на sum+=1/i и поставить спецификатор %f в последнем printf(). Однако после запуска на экране появится число 1. Почему? Данная проблема затрагивалась в теме «Операции и выражения» в разделе «Приведение типов». Дело в том, что оператор деления в некотором смысле интеллектуальный: он возвращает значение целого типа, если оба аргумента целые, а вещественным значение является только в том случае, когда хотя бы одно из значений вещественное. Поэтому решить данную проблему можно двумя способами:

float_sum += (float) 1/i;

float_sum += 1.0/i;