Цикли
Проблем
Колко ще спестиш?
Решаваш да спестяваш: първия месец отделяш 10 €, втория 20 €, третия 30 € и все така с по 10 € повече. Колко ще имаш след 4 месеца?
int total = 0;total += 1 * 10;total += 2 * 10;total += 3 * 10;total += 4 * 10;Console.WriteLine(total);100Работи. Но след 3 години ще са 36 реда, почти еднакви. А ако броят на месеците се въвежда от клавиатурата, изобщо не знаеш колко реда да напишеш. Трябва ти начин да кажеш „повтори това толкова пъти“.
Идеята
for: повтори, докато условието е вярно
Повтарящото се парче код се казва цикъл. Най-често ползваният е for. Ето числата от 1 до 10:
for (int i = 1; i <= 10; i++){ Console.WriteLine(i);}12345678910В скобите има три части, разделени с ;:
- Начало:
int i = 1. Изпълнява се веднъж, преди всичко останало. Тук се създава броячът. - Условие:
i <= 10. Проверява се преди всеки кръг. Ако е вярно, тялото се изпълнява. Ако не е, цикълът свършва. - Стъпка:
i++. Изпълнява се след всеки кръг.
Всяко изпълнение на тялото се казва итерация или просто кръг.
По-точно, за любопитните
- Стъпката може да е каквато ти трябва:
i += 2(през едно),i--(назад). - Броячът
iсъществува само вътре в цикъла. След затварящата}го няма и ако го ползваш, програмата не се компилира. - Често ще видиш броене от 0:
for (int i = 0; i < 10; i++). Пак е 10 кръга. Защо се брои от 0, ще стане ясно в урока за масивите.
Виж го
Кръг по кръг
Това са спестяванията от първата карта, с цикъл. Следи как се сменят month и total.
int total = 0;for (int month = 1; month <= 4; month++){ total += month * 10;}Console.WriteLine(total); // 100Стъпка по стъпка, с думи
- total започва от 0.
- month = 1. Проверка: 1 <= 4 е вярно, влизаме в тялото.
- Кръг 1: total += 1 * 10, total става 10.
- month++ прави month 2. 2 <= 4: още един кръг, total става 30.
- month 3: total става 60.
- month 4: total става 100.
- month++ прави month 5. 5 <= 4 е невярно: цикълът свършва.
- След цикъла total е 100.
Тялото е един ред и е написано веднъж. За 36 месеца сменяш само 4 на 36. А можеш да сложиш там и променлива, прочетена от клавиатурата.
Пробвай
Обратно броене
Какво ще отпечата програмата?
for (int sec = 3; sec > 0; sec--){ Console.WriteLine(sec);}Console.WriteLine("Старт!");sec-- намалява брояча след всеки кръг. Когато sec стане 0, условието sec > 0 е невярно и цикълът спира, без да отпечата 0. Редът след цикъла се изпълнява накрая, веднъж.Идеята
while: докато не дойде краят
Понякога не знаеш предварително колко кръга ще има. Касата чете цени, докато касиерът не въведе 0, и тогава казва сметката. Тук for не пасва. Пасва while: само условие, без начало и стъпка.
int total = 0;int price = int.Parse(Console.ReadLine());while (price != 0){ total += price; price = int.Parse(Console.ReadLine());}Console.WriteLine("Общо: " + total + " €");12470Общо: 23 €Първата цена се чете преди цикъла, за да има какво да провери условието. Следващата се чете в края на тялото. Ако първото число е 0, тялото не се изпълнява нито веднъж.
Ако искаш тялото да се изпълни поне веднъж, има do-while. Условието е отдолу и се проверява след кръга. Удобно е за въпрос, който се повтаря, докато отговорът не стане приемлив:
int count;do{ Console.WriteLine("Колко билета (от 1 до 10)?"); count = int.Parse(Console.ReadLine());} while (count < 1 || count > 10);Console.WriteLine("Запазени билети: " + count);0153Колко билета (от 1 до 10)?Колко билета (от 1 до 10)?Колко билета (от 1 до 10)?Запазени билети: 3По-точно, за любопитните
- Ако условието никога не стане невярно, цикълът не свършва. Това е безкраен цикъл: програмата „увисва“ и трябва да я спреш ръчно. Най-честата причина е забравена промяна на променливата в условието, например липсващо
price = …в края на тялото. -
След
while (…)на do-while има;. Без нея програмата не се компилира. - Всеки for може да се напише като while и обратно. Избираш този, който се чете по-ясно:
forза известен брой кръгове,whileза „докато нещо стане“.
Пробвай
Намери грешката
Програмата трябва да събере числата от 1 до 5: 1 + 2 + 3 + 4 + 5 = 15. Отпечатва 10. На кой ред е грешката?
Избери реда с грешката.
С i < n цикълът спира, преди i да стане 5, и 5 не се добавя: 1 + 2 + 3 + 4 = 10. Трябва i <= n.
Такава грешка с един кръг повече или по-малко е най-честата при циклите. Проверката „на сухо“ я хваща: разпиши i и sum за всеки кръг на лист.
Идеята
break и continue
Две думи сменят обичайния ход на цикъла.
continue прескача останалото от текущия кръг и минава на следващия. Записваш часове за прегледи от 9 до 17, но в 13 е обедната почивка:
for (int hour = 9; hour <= 17; hour++){ if (hour == 13) { continue; } Console.WriteLine(hour + ":00");}9:0010:0011:0012:0014:0015:0016:0017:00break спира целия цикъл веднага. Търсиш първото число, на което 91 се дели. Щом го намериш, няма смисъл да продължаваш:
int n = 91;for (int d = 2; d < n; d++){ if (n % d == 0) { Console.WriteLine(n + " се дели на " + d); break; }}91 се дели на 7По-точно, за любопитните
breakспира само цикъла, в който се намира. Ако е във вложен цикъл (следващата карта), външният продължава.- Често ще срещнеш while (true) с break вътре: цикъл, който свършва не от условието, а от break на подходящото място.
Идеята
Цикъл в цикъл
Залата на киното има 3 реда по 4 места. Искаш да отпечаташ всички места. За всеки ред минаваш през всички места в него:
for (int row = 1; row <= 3; row++){ for (int seat = 1; seat <= 4; seat++) { Console.Write("[" + row + "-" + seat + "]"); } Console.WriteLine();}[1-1][1-2][1-3][1-4][2-1][2-2][2-3][2-4][3-1][3-2][3-3][3-4]Това се казва вложени цикли. Вътрешният цикъл минава целия си път при всеки кръг на външния: 3 реда · 4 места = 12 отпечатвания. Write оставя местата на един ред, а празното WriteLine() след вътрешния цикъл слиза на нов ред.
Пробвай
Стълбичка
На първия ред трябва да има една звездичка, на втория две, на четвъртия четири. Какво трябва да пише на празното място?
for (int row = 1; row <= 4; row++)
{
for (int star = 1; star <= ; star++)
{
Console.Write("*");
}
Console.WriteLine();
}Вътрешният цикъл трябва да се върти толкова пъти, колкото е номерът на реда. Затова границата му е row, броячът на външния цикъл.
Идеята
Случайни числа за игрите
За игра на зарове трябва число, което програмата не знае предварително. Дава го Random:
Random random = new Random();int dice = random.Next(1, 7);Console.WriteLine("Хвърли " + dice);Random е обект, затова се създава с new. Какво е обект, ще разберем в модул „Класове и обекти“. Засега го ползвай така: създаваш го веднъж и после искаш от него числа колкото ти трябват.
random.Next(1, 7) дава число от 1 до 6: долната граница влиза, горната не.
Всяко пускане дава различно число, затова тук няма изход. Ето и цикъл, който хвърля, докато не се падне шестица:
Random random = new Random();int rolls = 0;int dice;do{ dice = random.Next(1, 7); rolls++;} while (dice != 6);Console.WriteLine("Шестица след " + rolls + " хвърляния");По-точно, за любопитните
- Ако дадеш на
Randomначално число (new Random(42)), всяко пускане дава една и съща поредица. Това помага при тестване. Java и C# дават различни поредици от едно и също начално число.
- Числата не са истински случайни: смятат се по формула. За игри стигат, за пароли и сигурност не.
Упражнение
Задачи с цикли
Реши задачите в редактора си. За всяка има примерен вход и изход, с който да сравниш своя. Числото се чете както в урока „Вход и изход“.
1. Таблица за умножение. Прочети число и отпечатай произведенията му с числата от 1 до 10.
77 x 1 = 77 x 2 = 147 x 3 = 217 x 4 = 287 x 5 = 357 x 6 = 427 x 7 = 497 x 8 = 567 x 9 = 637 x 10 = 702. Просто число. Едно число е просто, ако се дели само на 1 и на себе си: 2, 3, 5, 7, 11… Прочети число и кажи дали е просто. Подсказка: опитай делителите от 2 нагоре и спри с break при първия.
9191 не е простоЗа 11 изходът е „11 е просто“.
3. Цифрите на число. Прочети цяло положително число. Отпечатай го наобратно и сумата на цифрите му. Подсказка: n % 10 е последната цифра, а n / 10 маха последната цифра. Повтаряй, докато числото не стане 0.
2024Обратно: 4202Сума на цифрите: 84. Познай числото. Компютърът „намисля“ число от 1 до 100, а ти го търсиш. След всеки опит програмата казва „По-малко е.“ или „По-голямо е.“, а накрая колко опита ти е отнело. Първо го напиши с тайно число 37, за да провериш с примера:
502537По-малко е.По-голямо е.Позна от 3 опита!Когато работи, смени 37 със случайно число от 1 до 100. Вече и ти не знаеш отговора.
Още задачи
- От 1 до N. Прочети N и отпечатай числата от 1 до N на един ред. За 5:
1 2 3 4 5. - Факториел. N! = 1 · 2 · 3 · … · N. За 5: 120. Ползвай
long:intстига само до 12!, аlongдо 20! (2432902008176640000). - Прости числа до N. Отпечатай всички прости числа до N. За 20:
2 3 5 7 11 13 17 19. Проверката от задача 2 отива вътре в цикъл по числата: вложени цикли. - Фибоначи. Всяко число е сумата на предишните две: 0, 1, 1, 2, 3, 5, 8… Прочети N и отпечатай първите N числа. За 10:
0 1 1 2 3 5 8 13 21 34. - Квадрат от звездички. Прочети N и отпечатай квадрат N × N. За 3:
* * ** * ** * *- Триъгълник от звездички. Същото, но на всеки ред толкова звездички, колкото е номерът му. За 3:
** ** * *- Хвърляне на монета. Прочети N, хвърли монета N пъти със случайно число (0 е ези, 1 е тура) и отпечатай колко пъти се е паднало всяко. Колкото по-голямо е N, толкова по-близо са двете числа до N / 2.
- Камък, ножица, хартия. Играч срещу компютър. Играчът въвежда избора си, компютърът избира случайно, програмата казва кой печели. С do-while пита „Още една игра? (да/не)“ и накрая отпечатва резултата.
Тест