04:08 

Учимся программировать на С++. Лекция 11. Циклы

ToxicSpider
Бритуля - Богиня
Привет всем программистам))))

Условие:

1. Объявите массив float, длиной 3 элемента, заполните его начальными значениями, отличными от нуля.
2. Распечатайте значения.
3. Объявите указатель на float и присвойте ему адрес первого элемента в массиве, созданном на шаге (1)
4. Распечатайте значения массива, созданного на шаге (1) через указатель.
5. Поменяйте значение 2-го элемента "напрямую"
6. Поменяйте значение 3-го элемента через указатель, объявленный на шаге (3)
7. Выполните шаги 2 и 4 еще раз


Код:




Результат:







На прошлой лекции речь шла о массивах. Представим, что у нас есть массив, размером в 30 ячеек и мы хотим все их распечатать на экран. Единственный способ, который нам пока известен, это такой:

cout << arr [0] << endl;
cout << arr [1] << endl;
cout << arr [2] << endl;

и так до 30. Ну, вполне ожидаемо то, что я скажу: а теперь представьте, что их 3000.... как быть? Как мы заметили, что строки отличаются между собой лишь числом в ячейке, а все остальное - одинаково. Было бы проще создать блок, и сказать программе: "повторяй этот блок с начала до конца, каждый раз для другой ячейки массива, пока не пройдешь по всему массиву", а во внутрь блока положить нашу строку распечатки.

Блок, который будет повторятся, пока не выполнит задачу, называется "цикл"

В С++ существует 3 формы создать цикл и программист выбирает одну из них, в зависимости от его нужд. Мы изучим их все, по порядку.

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


Укороченные арифетические действия.


У нас есть переменная num:

int num = 0;

мы хотим увеличить эту переменную на 5. Другими словами, получить число, которое уже лежит в переменной, прибавить к ней 5 и положить обратно, в ту же переменную. Можно это сделать так:

num = num + 5;

НО! Если у нас такая ситуация, в которой, мы увеличиваем переменную, то есть по обе стороны знака "равно" - есть одна и та же переменная, то можно использовать сокращенную запись:

num += 5;

Обе эти записи приведут к одному и тому же результату. Они - абсолютно одинаковы по своей функции. Естественно, что это работает не только с константами, тот же фокус можно сделать, вот так:

int num1 = 3;
int num2 = 4;


можно так:

num1 = num1 + num2;

а можно сокращенно:

num1 += num2;

это тоже самое. Тот же фокус работает со всеми арифметическими действиями:

num1 = num1 * num2; ИЛИ num1 *= num2; // умножение.

То же самое можно сделать с делением и вычитанием, но так, как 5 - 3 НЕ равно 3 - 5, я никогда не пользуюсь этим в делении или вычитании. Поэтому, даже не знаю, что именно будет выполнено.

Однако, часто используется увеличение и уменьшение числа на 1. И для этой формы арифметического действия придумали еще более короткую запись:

int num = 10;

num ++; // имя переменной, а после этого два знака "плюс" - означает num = num + 1;

num --; // имя переменной, а после этого два знака "минус" - означает num = num - 1;


Последнее, что хочу сказать об этом действии, это порядок выполнения действий ++ и --.

Допустим код:

int a = 0;
int b = 5;

a = b++;
// в а было положено 5, а после этого b увеличили на 1. То есть, после выполнения этой строки, а равно 5, а b равно 6.


Другой код:

int c = 0;
int d = 5;

c = ++d;
// заметили? знак ++ перед переменной! Это означает: в начале выполни увеличение на 1, а потом - используй новое значение.
То есть, произошло следущее: в начале увеличили d на 1, то есть оно теперь равно 6, а после в с положили это значение, то есть: d, с равны 6

Как видите, разница есть! То же самое работает и с -- . Отлично! С этими знаниями мы углубимся в изучение циклов)))



Цикл while


Как всегда, по традиции, начнем с кода:




Разберем:
1. мы объявили массив чисел arr, размером в три ячейки и положили туда числа: 41, 42, 43
2. мы объявили переменную, у которой будут такие функции: во-первых, она будет увеличиваться на один каждый шаг цикла, во-вторых - мы постоянно будем с помощью нее запрашивать каждый раз новую ячейку, а в-третьих, мы будем с помощью нее проверять, что мы не вышли за границы цикла.

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

В блоке он выполнит следущее: распечатает строку и увеличит i на один.

Чтобы лучше понять это, посмотрим на это дело пошагово:


Первый шаг цикла, i равно 0:




Второй шаг цикла, i равно 1:




Третий шаг цикла, i равно 2:




Четвертый шаг цикла, i равно 3:




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



Цикл do-while


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




Для начала, я объясню, что делает программа. Программа просит у пользователя ввести число от 2 до 5 и если число введено правильно, то высвечивает его на экран, в противном случае - повторяет просьбу заново, пока пользователь не введет правильное число.

Теперь о синтаксисе:
Блок начинается со слова do, код попадает в блок. Выполняется код в блоке, а затем, после закрывающей скобки, пишется слово while в котором и написано условие. Если условие правда, то блок выполнится еще раз. Обратите внимание! после условия while стоит точка с запятой!

Как легко заметить, изначально, переменная input равна 3, то есть, если поменять этот цикл, на цикл while, о котором говорилось выше, алгоритм НИКОГДА не попадет в блок! Ну, а в случае с циклом do-while, так как условие проверяется в конце, алгоритм выполняет первый шаг в любом случае.

Перепишите код и запустите, чтобы лично во всем убедиться.

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


Цикл for


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

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

Схема:

for ( 1 ; 2 ; 3 ) { блок }

Где:

1. действие, которое будет выполнено только один раз, в момент, когда алгоритм впервые попадет в цикл

2. условие

3. действие, которое надо выполнить после каждого шага цикла


Вот теперь можно писать код. Я напишу тот же код, который привел в пример в цикле while:



Отлично. Разберите этот код, чтобы убедиться, что в нем все понятно. Обратите внимание! Присвоение i = 0 произойдет ТОЛЬКО один раз, во время первого попадания в цикл! Советую остановится на этом примере, пока все не будет досконально понятно! Я часто встречал людей, у которых этот цикл не усваивается легко.

Теперь, я внесу изменение. Как я уже говорил, в С++ есть возможность объявлять переменную там, где она нужна. Например, переменная i нужна только в цикле, вне цикла она не имеет применения, поэтому, обычно ее объявляют в самом цикле, то есть, пишут так:



Я объявил переменную и сразу присвоил ей значение 0 в скобках цикла!

Примечание: так как переменная i объявлена в блоке цикла, то как только алгоритм покинет блок - переменная i перестанет существовать.

Теперь, еще маленькое дополнение. Как я уже упоминал, во время изучения блока if-else, если код в блоке имеет всего одну строку, то скобки блока можно не писать, то есть, допустима запись:



Это же допустимо и с другими циклами.

Перепишите код и запустите.

Примечание: блок for можно писать без любого из трех вещей в круглых скобках. Он будет работать, однако, точка с запятой быть обязана. К примеру, нам, по какой-то причине нужна переменная i после цикла, чтобы, например, распечатать после цикла, сколько шагов было сделано. Тогда мы напишем такой код:



Как мы видим, значение, которое я в самом начале обозначил цифрой один - пропущено. Точно так же можно пропустить любое из других, не забыв, однако точку с запятой. Естественно, если мы пропустим условие, оставив его пустым, то цикл for будет выпонятся бесконечно.


Специальные инструкции в теле цикла


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


Инструкция break

Это уже знакомая нам инструкция по блоку switch-case. В цикле она работает так: Если алгоритм ее достиг, то он моментально покинет цикл, даже не закончив его. Как правило, такая инструкция окружена условием if. Я напишу тот же пример, который использовал в цикле do-while, с изменением. А именно: программа попросит пользователя ввести число от 2 до 5, НО! Если пользователь введет ноль - то алгоритм покинет блок. Специально, самым последним действием я распечатаю строку, чтобы, когда вы перепишите код и запустите, было видно, что встретив инструкцию break до этой строки, он ее не распечатает:



Перепишите, запустите. Обратите внимание, что строка "after break" не распечатывается, если ввести 0.


Инструкция continue

Инструкция continue ставится тогда, когда мы хотим пропустить какой-то определенный шаг. Тогда цикл начнется заново, а в случае for еще будет выполнено действие в круглых скобках, помеченное у меня на схеме выше как 3.
Для наглядного примера, программа, которая распечатывает в цикле массив. НО! Она распечатывает значение ячейки только в том случае, если оно нечетное:



Алгоритм, встретив инструкцию continue, пропустит код, написанный далее и зайдет в цикл заново.

Перепишите, запустите.



Бесконечные циклы


Есть определенный вид программ, в которых встречаются бесконечные циклы. Как можно сделать цикл бесконечным? Очень просто, сделать так, чтобы условие всегда было правдой. Несколько примеров:

while ( true ) { блок } // так, например, делаю я

while ( 42 ) { блок } // так делают программисты, привыкшие к С, где не было переменной bool. Почему 42? Общепринятый прикол. Помним, что все, отличное от нуля - правда, 42 - в том числе

while ( 1 == 1 ) { блок } // 1 всегда равно 1. То есть - всегда правда

for( ; ; ) { } // как я упоминал выше, пустое условие в цикле for делает его бесконечным


Примечание: инструкции continue и break работают и в этих циклах по тем же законам.


Вот и все, для этой лекции - вполне достаточно.



Домашнее задание:


Напишите программу, которая подсчитывает количество больших и маленьких букв в предложении. Результаты подсчета выведите на экран.

Запустите программу с фразой "I LiKe C++"

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

Подсказка: убедитесь, что вы помните о том, как строится стринг.

Для крутых:
Если вы считаете, что абсолютно поняли не только этот материал, но и все предыдущие, то напишите цикл подсчета так, чтобы вместо "шагающей переменной" i был использован указатель на char. Это задание на 5+ ))))

Удачи!

@темы: C++

URL
   

Godney

главная