Computers · November 15, 2021 0

10. Loops -1

ছোটবেলা থেকেই আমরা জানি যে পৃথিবী সূর্যের চারপাশে ঘুরে, কোন একটা নির্দিষ্ট জায়গা থেকে সূর্যের চারপাশ দিয়ে ঘুরে আবার ঐ নির্দিষ্ট জায়গায় ফিরে আসতে পৃথিবীর ১ বছর সময় লাগে। আবার শুনেছি প্রাচীন কালের মানুষ মনে করত সূর্য, চাঁদ সবাই নাকি পৃথিবীকে কেন্দ্র করে ঘুরে, তো যে যাকেই কেন্দ্র করে ঘুরুক তারা সবাই যে একই কাজ একই নিয়মে বারবার করতেছে বা একই কাজের পুনরাবৃত্তি ঘটতেছে এইটাই মূলত লুপের কাজ আর পুনরাবৃত্তি ঘটার ব্যপারটাকে বলা হয় ইটারেশন, ইটারেশন এর বাংলা অর্থই হল পুনরাবৃত্তিতো loop এর কাজ হল কোনো প্রোগ্রামে একটা statement বা এক ব্লক statement এর পুনরাবৃত্তি ঘটানো।

তাহলে loop হল একটা ধারা বা প্রক্রিয়া যার শুরু এবং শেষ পরস্পরের সাথে কানেক্টেড, অর্থাৎ যেখান থেকে শুরু হয় আবার সেখানটাই এসে শেষ হয়, এই চক্রাকার স্বভাবের জন্য এদেরকে loop বলা হয়। আমরা তো Variable vs Data Type -3 থেকে স্ক্রিনের উপর কোনো কিছুকে প্রিন্ট করা শিখেছি, ওখানে একবার cout<<“welcome to our dream world\n”<<endl; লেখার জন্য আমরা একবার welcome to our dream world প্রিন্ট করতে পেরেছি কিন্তু ঐ বাক্যটা যদি আমার ১০০ বা ১০০০ বার লিখতে ইচ্ছা হয় অথবা আমার মন চাচ্ছে আমার জন্মদিনে বোর্ড ভর্তি করে ১০০ বার iloveu@mom লিখতে তখন কি আমি


উপরের ছবির মতো করে ১০০ বার cout<<“iloveu@mom”<<endl; লিখবো? ummmমোটেও না, যেহেতু আমি একই জিনিস ১০০ বার প্রিন্ট করতে চাচ্ছি সেহেতু আমি একটা লুপ ব্যবহার করে সহজেই কাজটা করতে পারি।

যেমন,
for(int i=1; i<=100; i++)
{
cout<<“iloveu@mom”<<endl;
}
এই কোড লিখে কম্পাইল ও রান করলে ১০০ লাইনে ১০০ বার iloveu@mom প্রিন্ট করবে। বিশ্বাস না হলে নিচের ছবিটি দেখি:

:: বোল্লা যে ১০০ বার প্রিন্ট করবে, এতো দেখি ৯ বার প্রিন্ট করেছে
:- কোডের মধ্যে দেখো i<10 দিয়েছি তারমানে i=9 পর্যন্তই লুপ চলবে এজন্য এখানে ৯ বার iloveu@mom প্রিন্ট করেছে আর <<endl এর জন্য প্রত্যেকটা লাইন নতুন লাইনে প্রিন্ট হয়েছে।
:: অ

এখন দেখি এখানে কি কি ঘটতেছে:
for (initialization=1; condition<10; update++)
{
body of loop;
}
initialization: ১ম অপশন হলো initialization যা শর্তের সুচনা বিন্দুকে initialize করে এবং একবার মাত্র execute করে। এখানে i নামের একটা integer type এর variable নিয়ে তার মধ্যে 1 রেখেছি যা এখানে শর্তের সুচনা বিন্দু হিসেবে কাজ করছে। কোনো ইটারেশন বা পুনরাবৃত্তি ঘটার আগেই এই initialization এর ভ্যালুটা নির্দিষ্ট করতে হয়।

Condition: ২য় অপশন হলো condition, উপরের initialization কে যদি condition এ চেক করে সত্য হয় তাহলেই কেবল কম্পাইলার ব্লক বা “body of loop” এর মধ্যে গিয়ে কমান্ড অনুসারে কাজ করবে আর মিথ্যা হলে ব্লকের মধ্যে ঢুকবেনা। এখানে আমাদের সুচনা বিন্দু ছিলো ১ আর কন্ডিশনে রেখেছি less than 10 তো condition এ এসে ১ কে চেক করা হচ্ছে যে সে ১০ এর চেয়ে ছোট কিনা, আমরা সবাই জানি যে ১, ১০ এর চেয়ে ছোট তাই কন্ডিশন সত্য হলো, এভাবে যতবার কন্ডিশন সত্য হবে ততবার লুপ ঘুরবে। এটাকে শর্তের সীমানা বিন্দু বলা যায় অর্থাৎ এই কন্ডিশনই লুপের ইটারেশন বা পুনরাবৃত্তি কতবার চলবে সেটা নির্দেশ করে। initialization এর পরেই condition এর ভ্যালু বা loop এর সীমা নির্দেশ করতে হয়।

update: ৩য় অপশন হলো initialization এর আপডেট, এখানে i++ অর্থ হলো i = i+1 অর্থাৎ i এর মান এক এক করে বাড়াও। তারমানে শুরুতে i এর মধ্যে 1 রেখেছিলাম এখন তার মান আরো ১ বেড়ে হলো ১+১ = ২। অর্থাৎ initialization কে আপডেট করার পর সেই আপডেটেড ভ্যালু (২) যদি condition এ চেক করে (2<10) সত্য হয় তাহলে কম্পাইলার আবারো ব্লক বা “body of loop” এর মধ্যে গিয়ে কমান্ড অনুসারে কাজ করবে আর মিথ্যা হলে ব্লকের মধ্যে ঢুকবেনা।
উপরের আলোচিত তিনটি অপশনই মূলত লুপকে কন্ট্রোল করে।

তো আমাদের ২য় কন্ডিশনে ১<১০ সত্য ছিলো, তাই কম্পাইলার ব্লকের মধ্যে ঢুকে একবার iloveu@mom প্রিন্ট করল, কিন্তু তার সামনে একটা স্পেস নিয়ে 1. প্রিন্ট করেছে (উপরের আউটপুট দেখি) কারন cout কমান্ডে আমরা ওভাবে প্রিন্ট করতে বলে দিয়েছি। তারপর i এর মান ১ বেড়ে ২ হলো, তো ২<১০ সত্য, তাই কম্পাইলার ব্লকের মধ্যে ঢুকে ২য় বারের মতো iloveu@mom প্রিন্ট করল, তারপর ৩য়, ৪র্থ এভাবে ৯ বার iloveu@mom প্রিন্ট করল, সবশেষে i এর ভ্যালু ৯+১=১০ হলো কিন্তু ১০<১০ এটা তো সত্য না তাই ৯বার প্রিন্ট করার পর আর ঐ ব্লকের মধ্যে ঢুকলোনা, লুপের কাজ শেষ হয়ে গেলো।

এখন লুপ ব্যবহার করে ১ থেকে ১০ পর্যন্ত সংখ্যাগুলো প্রিন্ট করার প্রোগ্রাম লিখি:

এখানেও সুচনা বিন্দুতে i এর মান ১ যা ১০ এর চেয়ে ছোট, সুতরাং ১<১০ কন্ডিশন সত্য তাই লুপ একবার ঘুরেছে এবং এখানে i=1 তাই আউটপুটে 1 প্রিন্ট করেছে তারপর i এর মান ১ বেড়ে (১+১=২) ২ হয়েছে যা ১০ এর চেয়ে ছোট সুতরাং ২<১০ কন্ডিশনও সত্য তাই লুপ আরো একবার ঘুরেছে এবং i এর মান হিসেবে কে ২ প্রিন্ট করেছে তারপর i এর মান এক এক করে বেড়ে ৩, ৪, ৫ এভাবে ১০ পর্যন্ত হয়েছে এবং সেগুলোকে প্রিন্ট করেছে।

এখন ১ থেকে ১০ পর্যন্ত সবগুলো সংখ্যা যোগ করে সেই যোগফল প্রিন্ট করার প্রোগ্রাম লিখি:

এখানে প্রথমে n ও sum নামের দুইটা integer টাইপের variable নিয়ে sum এর মধ্যে জিরো রেখেছি আর n কে কিবোর্ড থেকে ইনপুট হিসেবে নেওয়ার কমান্ড দিয়েছি, তারপর আউটপুটে দেখি n এর মান ১০ নিয়েছি, লুপের মধ্যে প্রথম অপশন বা initialization এ i =1 নিয়েছি এবং i<=n বা 1<10 শর্তটি সত্য তাই কম্পাইলার লুপের মধ্যে ঢুকলো এবং দেখলো
sum = sum+i;
sum এর মধ্যে আমরা আগেই জিরো রেখেছিলাম এখন তাহলে
sum = sum+i বা, 0 = 0+1 হলো অর্থাৎ sum এর মধ্যে ০+১=১ থাকলো, তারপর লুপ ঘুরে i=2 হলো তাহলে
১ = ১+২ অর্থাৎ sum এর মধ্যে ১+২=৩ থাকলো, তারপর লুপ আবারো ঘুরে i=৩ হলো তাহলে
৩ = ৩+৩ হলো, এভাবে
৬ = ৬+৪
১০ = ১০+৫
১৫ = ১৫+৬
২১ = ২১+৭
২৮ = ২৮+৮
৩৬ = ৩৬+৯
৪৫ = ৪৫+১০
৫৫ = ৫৫+ আর লুপ ঘুরবেনা কারন এখানে i=11 হয়ে গেছে যা কিনা ১০ এর ছোট বা সমান না অর্থাৎ 11<=10 সত্য না তাই কন্ডিশন মিথ্যা হয়ে গেছে, তাহলে sum এর মধ্যে ফাইনাল ভ্যালু হিসেবে ৫৫ এসাইন হয়ে আছে এবং লুপ থেকে বের হয়ে cout<<sum কে দেখে sum এর ফাইনাল ভ্যালু ৫৫ কে প্রিন্ট করেছে, আর <<endl; দেখে ৫৫-র পর একটা নতুন লাইন প্রিন্ট করেছে তারপর Process returned 0 (0x0).. … হাবিজাবি প্রিন্ট করেছে, এগুলো সম্পর্কে আমরা Variable vs Data Type –4 থেকে কিছুটা জেনেছি পরে আস্তে ধীরে আরো জানা যাবে, এখনই চিন্তার কিছু নাই।

আচ্ছা আর নিচের কোডে ঐ কাজটাই মানে sum এর কাজটাই দুই ধাপে করেছি, প্রথম ধাপে, 1 থেকে n পর্যন্ত সবগুলো সংখ্যার প্রথম অর্ধেক বা n/2 সংখ্যক সংখ্যাকে যোগ করে sum এর মধ্যে রেখেছি তারপর ওই sum এর সাথে শেষ অর্ধেক সংখ্যাকে যোগ করে আবার ওই sum এর মধ্যে রেখেছি এবং সবশেষে sum কে প্রিন্ট করেছি। এখানে একটু খেয়াল করলে আমরা ফিল করতে পারব যে কম্পাইলার আসলে উপর থেকে কোড পড়তে পড়তে নিচের দিকে আসে।

এখানে প্রথম ধাপে ১ থেকে n/2 = 10/2 = 5 এর আগ পর্যন্ত বা 4 পর্যন্ত সব গুলো সংখ্যাকে যোগ করে (১+২+৩+৪ = ১০) ১০কে sum এর মধ্যে রেখেছে তারপর লুপ থেকে বের হয়ে ২য় লুপের মধ্যে ঢুকে আগের sum এর মধ্যে থাকা ১০ এর সাথে, n/2 বা 5 থেকে n বা ১০ পর্যন্ত বাকি অর্ধেক সংখ্যাকে যোগ করে (১০+৫+৬+৭+৮+৯+১০ = ৫৫) ফাইনাল যোগফলকে sum এর মধ্যে তার ফাইনাল ভ্যালু হিসেবে রেখে প্রিন্ট করেছে।
এখানে প্রথম লুপ থেকে বের হয়ে sum এর মধ্যে প্রথম অর্ধেকের যোগফল ১০ কে রেখেছে তারপর মেইন ফাংশনের শুরুতে ফিরে না গিয়ে পরবর্তি লুপের কাজ করেছে এজন্য আগের sum=10 এর সাথে পরবর্তি সংখ্যাগুলোকে যোগ করে ফাইনালি ৫৫ হয়েছে। প্রথম লুপ থেকে বের হয়ে যদি সে আবার শুরু থেকে কোড পড়ত তাহলে আবার sum=0 হয়ে যেত এবং তখন আমরা যোগফল হিসেবে ওই ১০ কেই পেতাম অথবা পরবর্তি লুপের (৫+৬+৭+৮+৯+১০ = ৪৫) ফলাফল ৪৫ কে পেতাম কিন্তু যেহেতু টোটাল সমষ্টি হিসেবে আমরা ৫৫ পেয়েছি অর্থাৎ কম্পাইলার উপর থেকে লাইন বাই লাইন কোড পড়তে পড়তে নিচের দিকে আসে।

আচ্ছা আর নিচের কোডে ১ থেকে ১০ পর্যন্ত সংখ্যাগুলো উল্টা ভাবে প্রিন্ট করেছি, তো ১০ কে সর্ব প্রথমে প্রিন্ট করার জন্য i এর ইনিশিয়াল ভ্যালু হিসেবে ১০ নিয়েছি, তারপর কনডিশনে চেক করেছি ১০, ১ এর চেয়ে বড় কিনা, তারপর আপডেটে গিয়ে i এর ভ্যালু এক এক করে কমিয়ে দিয়েছি, তো i এর ভ্যালু ১০ থেকে শুরু করে ৯, ৮, ৭ এভাবে যতক্ষন ১ এর ছোট বা সমান হবে ততক্ষন লুপের মধ্যে গিয়ে i এর ভ্যালু ১০, ৯, ৮, ৭ এভাবে ১ পর্যন্ত প্রিন্ট করবে তারপর শেষে i এর ভ্যালু ০ হলে, ০ >= 1 শর্তটি মিথ্যা হয়ে যাবে তাই প্রোগ্রাম লুপ থেকে বের হয়ে আসবে।

:: আমার একটা প্রশ্ন আছে
:- বলে ফেলো
:: এইযে আপডেটে যে ইনক্রিমেন্ট ডিক্রিমেন্ট হিসেবে i++ বা i– দিচ্ছি, যদি ++i বা –i দিই তাহলে কি হবে?
:- আচ্ছা নিচের প্রোগ্রামটা লিখে রান করে দেখি তাহলে কি হয়

প্রোগ্রামে দেখা যাচ্ছে আউটপুটের কোনো পরির্তন হয়নি, কারণ হচ্ছে ফর লুপ স্টেটমেন্টে ওই মানটি শুধু নিজেকে আপডেট করার জন্য ব্যবহার করছে। ওই নির্দিষ্ট সময়ে সে নিজেকে আগে/পরে যেভাবেই করুক, পরবর্তী স্টেটমেন্টে যাওয়ার আগে মান একই হবে এজন্য ফর লুপের ভিতরে ++i আর i++ অথবা i– ও –i এর মধ্যে কোনো পার্থক্য নেই।

আর looping statement গুলো ৩ ধরনের হয় 1. while loop 2. do while loop 3. for loop উপরে আমরা for loop নিয়ে আলোচনা করেছি। পরবর্তি পোষ্টে while loop নিয়ে আলোচনা হবে (ইনশাল্লাহ)।