10-dars: Sikllar — for, while, do-while
Dars haqida
Davomiyligi: 90 daqiqa Maqsad: Talaba for, while va do-while sikllarini tushunishi, har xil holatlarda qaysi biri mosligini bilishi va nested sikllar bilan ishlashi kerak.
1. Sikl nima?
Sikl (loop) — kodning takror-takror bajarilishi.
3-darsda pseudocode'da takrorlashni shunday yozgan edik:
REPEAT 10 TIMES:
bajar narsaC'da:
for (int i = 0; i < 10; i++) {
printf("Iteration %d\n", i);
}Bir xil g'oya — endi real C sintaksisida.
2. Nima uchun sikl?
Sikl'siz:
printf("1\n");
printf("2\n");
printf("3\n");
printf("4\n");
printf("5\n");
// ...100 marta...Sikl bilan:
for (int i = 1; i <= 100; i++) {
printf("%d\n", i);
}Kod 3 qator, lekin 100 marta ishlaydi.
3. for sikli tuzilmasi
for (initialization; condition; update) {
// body — har iteratsiyada ishlaydi
}3 ta qism:
Misol — 0 dan 9 gacha
for (int i = 0; i < 10; i++) {
printf("%d ", i);
}Natija: 0 1 2 3 4 5 6 7 8 9
Qadamma-qadam
1. i = 0
2. i < 10? → ROST
3. Body: printf("0 ")
4. i++ → i = 1
... har iteratsiyada 2-3-4 takrorlanadi ...
i = 10
2. i < 10? → YOLG'ON
3. Sikldan chiqadi4. Asosiy for misollar
1 dan 10 gacha
for (int i = 1; i <= 10; i++) {
printf("%d ", i);
}
// 1 2 3 4 5 6 7 8 9 10Teskari: 10 dan 1 gacha
for (int i = 10; i >= 1; i--) {
printf("%d ", i);
}
// 10 9 8 7 6 5 4 3 2 1Qadam bilan: toq raqamlar
for (int i = 1; i <= 20; i += 2) {
printf("%d ", i);
}
// 1 3 5 7 9 11 13 15 17 195. Yig'indi va faktorial
Yig'indi
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
printf("1+2+...+100 = %d\n", sum);
// 1+2+...+100 = 5050Faktorial
3-darsda flowchart bilan chizgan faktorial — endi C'da:
int n = 5;
int factorial = 1;
for (int i = 1; i <= n; i++) {
factorial *= i;
}
printf("%d! = %d\n", n, factorial);
// 5! = 1206. break va continue
break — sikldan chiqish
for (int i = 0; i < 100; i++) {
if (i == 5) {
break; // sikl tugaydi
}
printf("%d ", i);
}
// 0 1 2 3 4continue — keyingi iteratsiyaga
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // keyingi iteratsiyaga
}
printf("%d ", i);
}
// 1 3 5 7 9 (faqat toq)7. Nested for — sikl ichida sikl
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
printf("(%d, %d) ", i, j);
}
printf("\n");
}Natija:
(1, 1) (1, 2) (1, 3)
(2, 1) (2, 2) (2, 3)
(3, 1) (3, 2) (3, 3)Xuddi shu tuzilma bilan ko'paytirish jadvali chiziladi: tashqi sikl — qaysi jadval (2, 3, ..., 9), ichki sikl — 1 dan 10 gacha ko'paytirish.
8. Pattern (naqsh) chizish
Yulduzlar piramida
int n = 5;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
printf("*");
}
printf("\n");
}Natija:
*
**
***
****
*****O'rtali piramida
int n = 5;
for (int i = 1; i <= n; i++) {
// Bo'shliqlar
for (int j = 1; j <= n - i; j++) {
printf(" ");
}
// Yulduzlar
for (int j = 1; j <= 2 * i - 1; j++) {
printf("*");
}
printf("\n");
}Natija:
*
***
*****
*******
*********9. while sikli
while (shart) {
// body
}Shart rost bo'lguncha body takrorlanadi.
int i = 0;
while (i < 5) {
printf("%d ", i);
i++;
}
// 0 1 2 3 4for va while taqqoslash
for:
for (int i = 0; i < 5; i++) {
printf("%d ", i);
}while:
int i = 0;
while (i < 5) {
printf("%d ", i);
i++;
}Bir xil natija. Lekin:
- for — qachon nechta marta ishlashini oldindan bilamiz
- while — qancha marta ishlashini bilmaymiz
10. while qachon kerak?
Foydalanuvchi to'g'ri raqam kiritmaguncha
int yosh = -1;
while (yosh < 0 || yosh > 120) {
printf("Yoshingizni kiriting (0-120): ");
scanf("%d", &yosh); // scanf — foydalanuvchidan qiymat o'qiydi
}Cheksiz sikl
while (1) {
// cheksiz, faqat break bilan chiqadi
}11. do-while sikli
do {
// body
} while (shart);Avval body, keyin shart. Demak — kamida bir marta ishlaydi.
int i = 0;
do {
printf("%d ", i);
i++;
} while (i < 5);
// 0 1 2 3 412. while vs do-while farqi
int x = 10;
// while: shart yolg'on — bir marta ham ishlamaydi
while (x < 5) {
printf("while\n");
}
// do-while: avval body, keyin shart
do {
printf("do-while\n");
} while (x < 5);Natija:
do-whiledo-while bir marta ishladi, while umuman ishlamadi.
13. do-while qachon kerak?
Menu
int tanlov;
do {
printf("\n=== MENU ===\n");
printf("1. Yangi\n");
printf("2. Ochish\n");
printf("3. Saqlash\n");
printf("4. Chiqish\n");
printf("Tanlov: ");
scanf("%d", &tanlov);
// tanlovni qayta ishlash...
} while (tanlov != 4);Menu kamida bir marta ko'rinishi kerak.
Foydalanuvchi to'g'ri javob bermaguncha
char javob;
do {
printf("Davom etamiz? (h/y): ");
scanf(" %c", &javob);
} while (javob != 'h' && javob != 'y');14. Qaysi siklni tanlash?
| Holat | Sikl |
|---|---|
| Aniq N marta | for |
| Massiv bo'ylab | for |
| Foydalanuvchidan to'g'ri ma'lumot olish | do-while |
| Menu | do-while |
| Fayl o'qish | while |
| Shart asoslangan | while |
15. while bilan raqam masalalari
Raqamning son sonini topish
int n = 12345;
int count = 0;
while (n > 0) {
n = n / 10;
count++;
}
printf("Son soni: %d\n", count);
// Son soni: 5Har iteratsiyada n 10 ga bo'linadi. 12345 → 1234 → 123 → 12 → 1 → 0.
Teskariga aylantirish
int n = 12345;
int reverse = 0;
while (n > 0) {
reverse = reverse * 10 + n % 10; // n % 10 — oxirgi raqam
n /= 10; // oxirgisini olib tashlash
}
printf("Teskari: %d\n", reverse);
// 54321Palindrome (palindrom) tekshirish
Palindrom — teskari o'qiganda ham bir xil (121, 1331, 99).
int n = 121;
int original = n;
int reverse = 0;
while (n > 0) {
reverse = reverse * 10 + n % 10;
n /= 10;
}
if (original == reverse) {
printf("%d — palindrom\n", original);
} else {
printf("%d — palindrom emas\n", original);
}16. GCD: for va while yechimi
Eng katta umumiy bo'luvchi (GCD) — ikkala usulda.
for bilan (oddiy)
int a = 48, b = 18;
int gcd = 1;
for (int i = 1; i <= a && i <= b; i++) {
if (a % i == 0 && b % i == 0) {
gcd = i;
}
}
printf("GCD(%d, %d) = %d\n", a, b, gcd);
// GCD(48, 18) = 6while bilan (Euclidean — eng samarali)
int a = 48, b = 18;
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
printf("GCD: %d\n", a);
// GCD: 6Euclidean usuli ancha tezroq — katta raqamlarda ham bir necha qadam yetadi.
17. Cheksiz sikl, break va continue while'da
Cheksiz sikl va break
while (1) {
int input;
printf("Raqam kiriting (0 — chiqish): ");
scanf("%d", &input);
if (input == 0) {
break; // cheksizdan chiqish
}
printf("Kvadrati: %d\n", input * input);
}for (;;) { ... } — for bilan cheksiz siklning yana bir yozilishi.
continue while'da
int i = 0;
while (i < 10) {
i++;
if (i % 2 == 0) continue; // faqat toq
printf("%d ", i);
}
// 1 3 5 7 9Continue va increment
While'da continue ishlatganda — increment'ni continue'dan oldin qo'ying. Aks holda — cheksiz sikl!
// XATO — cheksiz!
int i = 0;
while (i < 10) {
if (i % 2 == 0) continue; // i hech qachon o'zgarmaydi!
printf("%d ", i);
i++;
}18. Common pitfalls
1. Off-by-one error
// XATO — 11 marta ishlaydi
for (int i = 0; i <= 10; i++) { ... } // 0,1,2,...,10 (11 marta)
// To'g'ri — 10 marta
for (int i = 0; i < 10; i++) { ... }
for (int i = 1; i <= 10; i++) { ... }2. Increment unutish — cheksiz sikl
int i = 0;
while (i < 10) {
printf("%d ", i);
// i++ unutildi — cheksiz!
}3. = vs ==
int x = 5;
while (x = 0) { ... } // XATO — belgilash, doim 0 (false)
while (x == 0) { ... } // To'g'ri4. O'zgaruvchini ichkarida e'lon qilish
for (int i = 0; i < 10; i++) {
int x = i * 2;
printf("%d\n", x);
}
// printf("%d\n", x); // XATO! x faqat for ichida ko'rinadi
// printf("%d\n", i); // XATO! i ham19. Murakkab misol: Raqam topish o'yini
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
int secret = rand() % 100 + 1;
int guess;
int attempts = 0;
printf("1-100 oralig'idagi raqamni toping!\n");
do {
printf("Sizning taxminingiz: ");
scanf("%d", &guess);
attempts++;
if (guess > secret) {
printf("Pastroq!\n");
} else if (guess < secret) {
printf("Balandroq!\n");
}
} while (guess != secret);
printf("Topdingiz! Urinishlar: %d\n", attempts);
return 0;
}scanf va foydalanuvchi bilan ishlashni keyinroq chuqurroq o'rganamiz — hozircha tayyor kod sifatida sinab ko'ring.
Darsdagi topshiriqlar
Topshiriq 1 — Asosiy for
asosiy.c — for sikli yordamida quyidagilarni alohida qatorlarda chiqaring:
- 1 dan 20 gacha sonlar
- 20 dan 1 gacha (teskari)
- 2 dan 50 gacha faqat juft sonlar
- 1 dan 50 gacha faqat toq sonlar
Maslahat: qadamni i += 2 bilan boshqaring.
Topshiriq 2 — Yulduzlar
stars.c — ichma-ich (nested) sikllar yordamida n = 5 uchun 4 xil yulduzcha naqshini chizing:
- Oddiy piramida (1, 2, 3... yulduzcha)
- Teskari piramida (n, n-1... yulduzcha)
- O'rtaga tekislangan (markazlashgan) piramida
- To'rtburchak (n qator, har birida 10 yulduzcha)
Topshiriq 3 — Tub sonlar
Tub son (prime) — faqat 1 va o'ziga bo'linadigan son.
primes.c — 1 dan 100 gacha barcha tub sonlarni topib chiqaring. Har bir sonni tekshirish uchun ichki sikldan foydalaning (i * i <= n gacha tekshirsa yetarli).
Topshiriq 4 — Raqam tahlili
number-analysis.c — berilgan butun son uchun while sikli yordamida quyidagilarni hisoblang va chiqaring:
- raqamlar soni (masalan 12345 → 5 ta)
- raqamlar yig'indisi (1+2+3+4+5)
- sonning teskarisi (12345 → 54321)
Maslahat: % 10 oxirgi raqamni, /= 10 esa oxirgi raqamni olib tashlashni beradi.
Boshqa raqamlar bilan sinab ko'ring.
Topshiriq 5 — do-while menu
menu.c — do-while sikli yordamida takrorlanuvchi menyu yozing:
- 5 ta tanlov chiqaring (masalan: Yangi fayl, Ochish, Saqlash, Chop etish, Chiqish)
- foydalanuvchi tanlovini
scanfbilan o'qing switchbilan har bir tanlovga mos xabar chiqaring- 5 (Chiqish) tanlanmaguncha menyu qaytadan ko'rsatilsin
Nega bu yerda while emas, do-while qulay — o'ylab ko'ring.
Topshiriq 6 — Collatz Conjecture
collatz.c — Collatz qoidasini while sikli bilan amalga oshiring:
- agar
njuft bo'lsa →n = n / 2 - agar
ntoq bo'lsa →n = 3 * n + 1 n1 ga yetguncha takrorlang, har qadamni va jami qadamlar sonini chiqaring
Sinab ko'ring: 1, 2, 3, 6, 7, 27, 97.
(Bonus: 27 uchun necha qadam kerakligini toping.)
Topshiriq 7 — for/while/do-while qaysisi?
Quyidagi vazifalarning har biri uchun eng mos siklni tanlang va dasturni yozing:
- 1 dan 100 gacha juft raqamlar yig'indisi
- Faktorial hisoblash (n ber, n! topish)
- Foydalanuvchi 0 kiritmaguncha raqamlarni qabul qilish va yig'indini topish
- Menu (3 ta tanlov)
- 2^n qachon 1 milliondan oshadi? (n = ?)
Har biri uchun:
- Qaysi sikl?
- Sabab?
Va dasturlarni yozing.
Topshiriq 8 — GitHub'ga
$ cd ~/c-darslari
$ mkdir 4-oy-dars-10
$ # fayllarni shu joyga
$ git add .
$ git commit -m "feat: dars 10 - loops"
$ git pushAsosiy tushunchalar (lug'at)
| Termin | Qisqacha izoh |
|---|---|
| Loop | Sikl, takrorlash |
| for | Aniq marta takrorlash sikli |
| while | Shart asoslangan sikl |
| do-while | Avval body, keyin shart |
| Iteration | Sikl bir bor ishlashi |
| Init | Boshlash (int i = 0) |
| Condition | Shart (i < 10) |
| Update | Yangilanish (i++) |
| break | Sikldan chiqish |
| continue | Keyingi iteratsiyaga o'tish |
| Nested loop | Sikl ichida sikl |
| Off-by-one | 1 ta xato (ortiq yoki kam) |
| Infinite loop | Cheksiz sikl |
| Pre-test loop | while (oldin shart) |
| Post-test loop | do-while (keyin shart) |
| Factorial | n! = n*(n-1)*...*1 |
| Prime | Tub son |
| Palindrome | Teskaridan bir xil |
| GCD | Greatest Common Divisor |
| Euclidean algorithm | Tezkor GCD usuli |
| Collatz conjecture | Matematik gipoteza |