Lesson পড়তে ৭ মিনিট লাগবে

লুপ (Loops)

কোডের (code) একটি অ্যাসেম্বলি লাইন (assembly line) — বাক্সটি পুরোপুরি না ভরা পর্যন্ত এটি এর ভেতরে সব স্ট্যাম্প (stamping) করতেই থাকে

অ্যাসেম্বলি লাইন (The Assembly Line)

ধরা যাক, একটি কারখানার (factory) অ্যাসেম্বলি লাইনের (assembly line) কথা। যেখানে একটি রোবটের হাত (robot arm) মূলত তার একটি পার্ট বা অংশ (part) তুলে নেয়, সেটির ওপর স্ট্যাম্প (stamps) মারে, বেলেটের (belt) ওপর রাখে এবং এই একই কাজ শত শত বার (hundreds of times) পুনরায় (repeats) করতে থাকে। এটি কখনোই বোর (bored) বা বিরক্ত হয় না, কোনো প্রকার কোনো ভুলও (mistakes) করে না (অবশ্য যদি না আপনি সেটিকে ভুলভাবে প্রোগ্রাম বা programmed করে থাকেন), এবং এর বাক্স বা বক্সটি (box) পুরো ভর্তি হওয়া মাত্রই এটি ঠিকঠাকমতো থেমে যায় (stops exactly)।

সি (C)-তে মূলত এই লুপগুলো (loops) ঠিক এভাবেই কাজ করে। এটি মূলত কোনো একটি নির্দিষ্ট শর্ত বা কন্ডিশন (condition) সেটিকে থামাতে না বলা পর্যন্ত কোডের (code) একটি নির্দিষ্ট ব্লককে (block) বারবার পুনরায় (repeat) চালাতে থাকে। সি (C) প্রোগ্রামিং মূলত এর প্রতিটি ভিন্ন বা আলাদা পরিস্থিতির (different situation) জন্য উপযুক্ত মোট তিনটি (three) ধরনের লুপ (loops) প্রদান করে থাকে:

  • for — যখন আপনি ঠিকঠাকমতো বা এক্সাক্টলি (exactly) জানেন যে আপনাকে কোনো জিনিস ঠিক কতবার পুনরাবৃত্তি (repeat) করতে হবে।
  • while — যখন আপনি এর নির্দিষ্ট কোনো একটি শর্ত বা কন্ডিশনের (condition) শেষ না হওয়া পর্যন্ত বারবার এর কাজগুলোকে পুনরাবৃত্তি (repeat) করতে চান।
  • do-while — এটি মূলত এই while-এর মতোই, তবে এটি অন্তত পক্ষে একবার (at least once) তার ভেতরের সমস্ত কাজগুলো রান (runs) করে।

ফর লুপ (The for Loop)

এই for লুপটি (for loop) মূলত এর সমস্ত জিনিসগুলোকে এক লাইনের (one line) ভেতরেই প্যাক (packs) করে নেয়: இனிশিয়ালাইজেশন (initialization) বা শুরু করা, কন্ডিশন (condition) বা শর্ত, এবং আপডেট বা হালনাগাদ (update)। সি (C)-তে এটি মূলত সবচেয়ে বেশি ব্যবহৃত বা কমন লুপ (common loop) এবং বিভিন্ন গণনার (counting) কাজে আপনি মূলত এটিকেই সবচেয়ে বেশি ব্যবহার করবেন।

সিনট্যাক্স (Syntax): for (init; condition; update) { body }

ফর লুপ (for Loop) — গণনা করা (Counting)

#include <stdio.h>
int main() {
// ১ (1) থেকে ৫ (5) পর্যন্ত গণনা (Count) করা
for (int i = 1; i <= 5; i++) {
printf("%d ", i);
}
printf("\n");
// ৫ (5) থেকে নিচের দিকে গণনা বা কাউন্ট ডাউন (Count down) করা
for (int i = 5; i >= 1; i--) {
printf("%d ", i);
}
printf("\n");
// ২ (2) করে লাফানো বা স্টেপ (Step) করা
for (int i = 0; i <= 10; i += 2) {
printf("%d ", i);
}
printf("\n");
return 0;
}
Output
1 2 3 4 5 
5 4 3 2 1 
0 2 4 6 8 10 

হোয়াইল লুপ (The while Loop)

এই while লুপ (while loop) মূলত তার প্রতিটি ইটারেশনের (iteration) বা পুনরাবৃত্তির আগেই (before) তার শর্ত বা কন্ডিশনটিকে (condition) যাচাই (checks) করে। তাই যদি এর ভেতরের শর্তটি (condition) শুরু থেকেই মিথ্যা বা ফলস (false) হয়, তবে এর ওই বডিটি (body) আর কখনই রান (runs) করে না। এটি আপনি মূলত তখনই ব্যবহার করবেন যখন আপনার আগে থেকেই জানা থাকে না যে এর ভেতর মোট কতগুলো পুনরাবৃত্তির (repetitions) প্রয়োজন।

হোয়াইল লুপ (while Loop) — অজানা ইটারেশনসমূহ (Unknown Iterations)

#include <stdio.h>
int main() {
// একটি সংখ্যা ০ (0)-তে পৌঁছানোর আগে আমরা সেটিকে ঠিক কতবার অর্ধেক (halve) করতে পারি?
int num = 1000;
int steps = 0;
while (num > 0) {
num /= 2; // ইন্টিজার ডিভিশন বা পূর্ণসংখ্যার ভাগ (Integer division)
steps++;
}
printf("It took %d halvings to reach 0\n", steps);
// কোনো সংখ্যার ডিজিটগুলোর যোগফল (Sum digits of a number)
int n = 9472;
int sum = 0;
int original = n;
while (n > 0) {
sum += n % 10; // শেষ বা লাস্ট (last) ডিজিটটি নেওয়া
n /= 10; // শেষ বা লাস্ট (last) ডিজিটটি মুছে ফেলা (Remove)
}
printf("Sum of digits of %d = %d\n", original, sum);
return 0;
}
Output
It took 10 halvings to reach 0
Sum of digits of 9472 = 22

ডু-হোয়াইল লুপ (The do-while Loop)

এই do-while লুপটি (do-while loop) মূলত একটি ট্রাই-দেন-চেক (try-then-check) বা চেষ্টা-করে-চেক-করা লুপ। এটি মূলত সবার আগে (first) এর বডিকে (body) রান (runs) করিয়ে নেয়, এবং ঠিক তার পরপরই এর শর্ত বা কন্ডিশনটিকে (condition) চেক (checks) করে। এর ফলে এটির বডিটি অন্তত একবার হলেও (at least once) এক্সিকিউট (executes) বা রান হয় — ইনপুট ভ্যালিডেশনের (input validation) জন্য এটি মূলত একেবারে পারফেক্ট বা নিখুঁত (perfect), যেখানে আপনাকে সাধারণত ইউজারের (user) কাছে কোনো কিছু চেয়ে নিয়ে দেখতে হয় যে সেটি সম্পূর্ণ বৈধ বা ভ্যালিড (valid) কি না।

ডু-হোয়াইল (do-while) — ইনপুট ভ্যালিডেশন (Input Validation)

#include <stdio.h>
int main() {
int choice;
// মেনু ইনপুট ভ্যালিডেশনকে (menu input validation) সিমুলেট বা অনুকরণ (Simulating) করা হচ্ছে
// (আসল বা real কোডে, এখানকার এই scanf মূলত প্রতিটি সময়েই ইউজারের 인পুটটিকে বা user input-কে রিড (read) করত)
choice = 3; // সিমুলেটেড বা অনুকরণ করা বৈধ ইনপুট (Simulated valid input)
do {
printf("Menu: 1=Play 2=Settings 3=Quit\n");
printf("You chose: %d\n", choice);
// আসল বা real কোডে: scanf("%d", &choice);
} while (choice < 1 || choice > 3);
printf("Valid choice: %d\n", choice);
// অন্তত একবার বা at least once আউটপুট জেনারেট (generating output) করার জন্য do-while লুপ ব্যবহার
int n = 0;
do {
printf("This prints even though n is %d\n", n);
} while (n > 0); // এর কন্ডিশনটি বা শর্তটি সম্পূর্ণ মিথ্যা বা false, তবে এর বডিটি বা body অন্তত একবার বা once রান করেছিল
return 0;
}
Output
Menu: 1=Play 2=Settings 3=Quit
You chose: 3
Valid choice: 3
This prints even though n is 0

ব্রেক এবং কন্টিনিউ (break and continue)

এখানকার এই break বা ব্রেকটি মূলত এর ইমারজেন্সি স্টপ বাটনটিকে (emergency stop button) ভেঙে দেয় — অর্থাৎ এটি তাৎক্ষণিকভাবে (immediately) ওই লুপটি (loop) থেকে বের হয়ে আসে (exits)। অন্যদিকে continue বা কন্টিনিউ মূলত বর্তমান ইটারেশনের (current iteration) বাকি অংশটুকুকে একেবারে স্কিপ (skips) বা এড়িয়ে গিয়ে সরাসরি এর পরেরটিতে (next one) লাফ দেয় (jumps)। এই for, while, এবং do-while-এর তিনটির ক্ষেত্রেই এই জিনিসগুলো খুব সুন্দরভাবে কাজ করে।

ব্রেক এবং কন্টিনিউ (break and continue)

#include <stdio.h>
int main() {
// ব্রেক (break): 50-এর ওপর 7-এর প্রথম গুণিতকটি বা মাল্টিপলটি (first multiple) খুঁজে বের করুন
for (int i = 51; i < 100; i++) {
if (i % 7 == 0) {
printf("First multiple of 7 over 50: %d\n", i);
break; // খোঁজা থামান (Stop searching)
}
}
// কন্টিনিউ (continue): শুধুমাত্র বিজোড় বা অড (odd) সংখ্যাগুলোকে প্রিন্ট (print) করুন
printf("Odd numbers 1-10: ");
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // জোড় বা ইভেন (even) সংখ্যাগুলোকে এড়িয়ে বা স্কিপ (Skip) করুন
}
printf("%d ", i);
}
printf("\n");
return 0;
}
Output
First multiple of 7 over 50: 56
Odd numbers 1-10: 1 3 5 7 9 

নেস্টেড লুপ (Nested Loops)

একটি লুপের (loop) ভেতরের আরেকটি লুপ (loop) — এখানকার ওই বাইরের লুপটির (outer loop) প্রতিটি সিঙ্গেল ইটারেশন (single iteration) বা পুনরাবৃত্তির জন্য মূলত এই ভেতরের লুপটি (inner loop) তার ভেতরের সমস্ত ইটারেশনগুলোকে (iterations) একে একে সম্পন্ন করে। ব্যাপারটিকে ঠিক কোনো ঘড়ির কাঁটার (clock hands) মতো করে দেখতে পারেন: যেখানে মূলত মিনিটের কাঁটার প্রতিটি টিকের (tick) জন্য সেকেন্ডের কাঁটাটি প্রায় ৬০ বার (60 times) পর্যন্ত ঘুরে আসে।

নেস্টেড লুপ (Nested Loops) — নামতা বা মাল্টিপ্লিকেশন টেবিল (Multiplication Table)

#include <stdio.h>
int main() {
printf("Multiplication Table (1-5):\n\n");
printf(" ");
for (int j = 1; j <= 5; j++) {
printf("%4d", j);
}
printf("\n --------------------\n");
for (int i = 1; i <= 5; i++) {
printf("%2d |", i);
for (int j = 1; j <= 5; j++) {
printf("%4d", i * j);
}
printf("\n");
}
return 0;
}
Output
Multiplication Table (1-5):

       1   2   3   4   5
    --------------------
 1 |   1   2   3   4   5
 2 |   2   4   6   8  10
 3 |   3   6   9  12  15
 4 |   4   8  12  16  20
 5 |   5  10  15  20  25
Note: ৩টি সাধারণ লুপ সমস্যা বা লুপ পিটফল (loop pitfalls) যা থেকে নিজেকে বাঁচিয়ে রাখা উচিত:
1. অফ-বাই-ওয়ান এরর (Off-by-one errors)<= বোঝাতে গিয়ে ভুল করে < ব্যবহার করা (অথবা এর ঠিক উল্টোটি)। এটি কি i < 5 (০-৪ পর্যন্ত চলবে বা runs 0-4) নাকি i <= 5 (০-৫ পর্যন্ত চলবে বা runs 0-5) হবে? এটি মূলত এখানকার লুপগুলোর (loop bug) সবথেকে কমন বা সাধারণ একটি ভুল।
2. ইনফাইনাইট লুপ বা অসীম লুপ (Infinite loops) — একটি while লুপের (loop) ভেতরের লুপ ভ্যারিয়েবলটিকে (loop variable) আপডেট (update) করতে ভুলে যাওয়া, অথবা এমন কোনো কন্ডিশন বা শর্ত (condition) লিখে ফেলা যা কখনোই মিথ্যা (false) হওয়ার কোনো সুযোগই নেই। এতে আপনার প্রোগ্রামটি (program) মূলত হ্যাং (hangs) হয়ে যায় বা আটকে থাকে এবং আপনাকে এটি কিল (kill) করতে বা বন্ধ করতে ওই Ctrl+C বোতামে চাপ দিতে হয়।
3. do-while সবসময় অন্তত একবার কাজ করে (do-while always runs once) — যদি আপনার লজিকটি (logic) মূলত এর কন্ডিশনটি ফলস বা মিথ্যা (false) হওয়ার কারণে এর বডিটিকে (body) পুরোপুরি এড়িয়ে যাওয়ার বা স্কিপ (skipping) করার দাবি করে, তবে এই do-while-এর বদলে শুধু while ব্যবহার করুন।

কমন বা সাধারণ প্যাটার্ন (Common Pattern) — লুপ দিয়ে যোগ করা (Summing with a Loop)

#include <stdio.h>
int main() {
// ১ (1) থেকে ১০০ (100) এর যোগফল (Sum)
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
printf("Sum of 1 to 100 = %d\n", sum);
// ১০ (10) এর ফ্যাক্টোরিয়াল (Factorial)
long factorial = 1;
int n = 10;
for (int i = 1; i <= n; i++) {
factorial *= i;
}
printf("%d! = %ld\n", n, factorial);
// এক সেট সংখ্যার (set of numbers) মধ্যে থেকে সর্বোচ্চ বা max (Find max) খুঁজে বের করা
int nums[] = {34, 78, 12, 95, 43, 67};
int max = nums[0];
for (int i = 1; i < 6; i++) {
if (nums[i] > max) {
max = nums[i];
}
}
printf("Max value: %d\n", max);
return 0;
}
Output
Sum of 1 to 100 = 5050
10! = 3628800
Max value: 95
চ্যালেঞ্জ

ছোট কুইজ

এই for (int i = 0; i < 5; i++)-এর বডিটি (body) মূলত ঠিক কতবার এক্সিকিউট (execute) বা রান হয়?
ConditionalsArrays