পাতা

গরুর গাড়ির দুই চাক্কা ঘুরঘুরাইয়া চলে

একটা ক্লাসটেস্ট তো হয়ে গেলে। এবার নেক্সট ক্লাসটেস্টের জন্য পড়াশোনা। স্বভাবতই স্যার আগের চেয়ে কঠিন কঠিন কাজ করতে দেবে। এবার ধপ করে তোমাকে কাজ দিয়ে বসল, তোমাকে নামতা লিখতে হবে। তুমি ভাবলে, সেটা আর এমন কী! কিন্তু, খানিকবাদেই স্যার আবারও সেটার সাথে শর্ত জুড়ে দিলেন। প্রতি নামতায় তোমাকে ১ থেকে ১০ নয় বরং ১০০ পর্যন্ত গুণফল লিখতে হবে। একই সাথে নামতা লিখতে হবে ৩১ থেকে ৪০ এর। অর্থাৎ ১০০ X ১০ মোট এক হাজারটা লাইন লিখতে হবে। শুনেই তোমার মাথায় হাত! এতকিছু কিভাবে লিখলে। একই সাথে তুমি খানিকটা বিরক্তও হলে। পুরো এক হাজার লাইনেই তোমাকে মোটামুটি একই কাজ করতে হচ্ছে। একটা নির্দিষ্ট সংখ্যাকে ক্রমান্বয়ে ১ থেকে ১০০ দিয়ে গুণ করিয়ে সমান চিহ্ন দিয়ে গুণফলটা লিখতে হচ্ছে। এই একই কাজ বারবার, বারবার, বারবার। তুমি ভাবতে থাকলে, যদি এমনটা করা যেত যে, আমি কাউকে বুঝিয়ে দিলাম, আমাকে এই গুণ করার কাজটা এভাবে প্রতিবার একটু একটু করে পরিবর্তন করে একশো বার লিখতে হবে, আর কাজটা সেভাবে হয়ে যেত!
মজার ব্যাপার হচ্ছে, প্রোগ্রামিংয়ে এমনটা সত্যিই করা যায়। ব্যাপারটাকে বলে লুপিং (Looping)। নাম শুনেই বোঝা যাচ্ছে, এর কাজই একই কাজ বারবার করা। লুপিং ব্যাপারটা অনেকটা এভাবে ঘটে - আমরা একটা নির্দিষ্ট শর্ত দিয়ে দিই। সেই শর্তটা যতক্ষণ সত্যি থাকে, ততক্ষণ সেটা কাজ করতে থাকে। If else এ আমরা যেমন দেখেছিলাম, একটা শর্ত যদি সত্য হয়, তাহলে সেটা একবার কাজ করে। লুপের স্পেশালিটিই হচ্ছে, যতক্ষণ শর্তটা সত্য হবে, ততক্ষণই কাজটা চলতে থাকবে বারবার এবং বারবার। এখানে মাথায় রাখার মত ব্যাপার হচ্ছে, যেহেতু যতক্ষণ শর্তটা সত্য ততক্ষণ একই কাজ হতেই থাকবে এবং হতেই থাকবে, তাই আমাদের লুপের ভেতরেই এমন কিছু করতে হবে, যেন একটু পরে সেই শর্তটা মিথ্যে হয়ে যায়। নইলে আমাদের লুপ অনন্তকাল চলতেই থাকবে এবং প্রোগ্রাম কখনও বন্ধ হবে না।

তাহলে আমাদের দশটা বিশাল বিশাল নামতা লেখার প্রোগ্রামটা লিখে ফেলা যাক।

  1. #include <stdio.h>
  2. int main(){
  3.     int n, i;
  4.     i = 1;
  5.     n = 31;
  6.     while(i<=100){
  7.         printf("%d X %d = %d\n", n, i, i*i);
  8.         i = i+1;
  9.     }
  10.     i = 1;
  11.     n = 32;
  12.     while(i<=100){
  13.         printf("%d X %d = %d\n", n, i, i*i);
  14.         i = i+1;
  15.     }
  16.     i = 1;
  17.     n = 33;
  18.     while(i<=100){
  19.         printf("%d X %d = %d\n", n, i, i*i);
  20.         i = i+1;
  21.     }
  22.     i = 1;
  23.     n = 34;
  24.     while(i<=100){
  25.         printf("%d X %d = %d\n", n, i, i*i);
  26.         i = i+1;
  27.     }
  28.     i = 1;
  29.     n = 35;
  30.     while(i<=100){
  31.         printf("%d X %d = %d\n", n, i, i*i);
  32.         i = i+1;
  33.     }
  34.     i = 1;
  35.     n = 36;
  36.     while(i<=100){
  37.         printf("%d X %d = %d\n", n, i, i*i);
  38.         i = i+1;
  39.     }
  40.     i = 1;
  41.     n = 37;
  42.     while(i<=100){
  43.         printf("%d X %d = %d\n", n, i, i*i);
  44.         i = i+1;
  45.     }
  46.     i = 1;
  47.     n = 38;
  48.     while(i<=100){
  49.         printf("%d X %d = %d\n", n, i, i*i);
  50.         i = i+1;
  51.     }
  52.     i = 1;
  53.     n = 39;
  54.     while(i<=100){
  55.         printf("%d X %d = %d\n", n, i, i*i);
  56.         i = i+1;
  57.     }
  58.     i = 1;
  59.     n = 40;
  60.     while(i<=100){
  61.         printf("%d X %d = %d\n", n, i, i*i);
  62.         i = i+1;
  63.     }
  64. }

প্রোগ্রামটা বোঝার আগে সবচেয়ে দারুন জিনিসটা খেয়াল করি, লুপ ব্যাবহার করার ফলে আমাদের তথাকথিত হাজার লাইনের প্রোগ্রামটা রাতারাতি ৬৫ লাইনে নেমে এসেছে। দারুণ না? এবার আমরা দেখি, এই দারুন ব্যাপারটা কিভাবে ঘটল। প্রথমে তো আমরা n আর i নামের দুটো ভ্যারিয়েবল ডিক্লেয়ার করে তাদের মান ঠিক করে দিয়েছি। তারপরে একটা শব্দ ব্যবহার করেছি - while. এই শব্দটাই মূলত আমাদের লুপিংয়ের কাজ করছে, এই while শব্দটার সাথে আমরা যে শর্ত জুড়ে দেব ( এক্ষেত্রে i এর মান যতক্ষণ 100 এর ছোট বা সমান) সেই শর্তটা যতক্ষণ সত্য থাকবে, ততক্ষণ এর {} বন্ধনীর ভেতরের কাজ চলতে থাকবে। লুপের ভেতরে আমরা প্রথমে বলেছি, যেন নামতার একটা লাইন প্রিন্ট করে। সেখানে n আর i এর মানের ওপর নির্ভর করে যা প্রিন্ট করা দরকার, তাই প্রিন্ট হবে। তারপরের লাইনটা অনেকের কাছে ঘোলাটে মনে হয়। তবে, জিনিসটা তেমন কিছুই না। এই লাইনে যা হয়, তা হচ্ছে, প্রথমে i এর বর্তমান যে মান, সেটার সাথে এক যোগ করা হয়। তারপর সেই যোগফলটাকে i এর ভেতরে রাখা হয়। যেমন, লুপের শুরুতে i এর মান 1। এই লাইনে এসে প্রথমে সেই 1 এর সাথে আরও 1 যোগ হবে। তারপর সেই যোগফল অর্থাৎ 2 ভ্যারিয়েবলের মান হিসেবে ঠিক করা হবে। আবার ধরি, লুপের কোন এক মুহূর্তে i এর মান 35। তাহলে প্রথমে 35 এর সাথে 1 যোগ করা হবে। তারপর সেই যোগফল অর্থাৎ 36কে i এর মান হিসেবে রাখা হবে। অর্থাৎ, মোদ্দাকথা হল, i এর মান যাই হোক না কেন, এই লাইনে এসে i এর মান এক বেড়ে যাবে। আমরা যদি এখানে i = i + 5 লিখতাম, তাহলে এখানে প্রতিবার এসে i এর মান 5 করে বেড়ে যেত।

এইটুকু বুঝে গেলে বাকিটুকু বুঝতে না পারার কোন কারণ নেই। কারণ, প্রায় একই কাজ বারবার করা হয়েছে কেবল পার্থক্যটুকু হচ্ছে, আমরা n (অর্থাৎ কত এর নামতা) সেটা বারবার ঠিক করে দিয়েছি। তারপর একই কাজের পুনরাবৃত্তি করেছি।

একটা লুপের মূল কাজই হচ্ছে, যে কাজটা আমাদের সামান্য একটু পরিবর্তন করে বারবার করতে হয়, সেটাকে একটা নির্দিষ্ট ফরম্যাটে গুছিয়ে সেটাকে বারবার ব্যবহার করা। এখন তোমাদের মনে আরেকটা প্রশ্ন জাগতে পারে যে, লুপের কাজ যদি একই কাজ বারবার করানো হয়, তাহলে আমাদের ওপরের প্রোগ্রামটায়ও তো আমরা একই কাজ বারবার করেছি। i আর n ভ্যারিয়েবলের মান ঠিক করে দিয়ে একটা while লুপ চালানোর কাজটা আমরা দশবার করেছি। এটাকে কি লুপ ব্যবহার করে একবার লিখে দশবার কাজ করানো যায় না। উত্তরটা হচ্ছে, অবশ্যই যায়। কাজটা করানোর জন্য আমাদের যা করতে হবে তা হচ্ছে, একটা লুপের ভেতরে আরেকটা লুপ চালানো। প্রথমত একটা লুপ দিয়ে আমরা বারবার n এর মান 1 করে বাড়াতে থাকব। আর ভেতরের লুপে n এর সেই একই মানের জন্য আবার i এর মান 1 থেকে 100 পর্যন্ত চালিয়ে n এর নামতা প্রিন্ট করব। লেখায় ব্যাপারটা একটু ভজঘট লাগতে পারে। তার পরিবর্তে আমরা প্রোগ্রামটাই লিখে ফেলি।

  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int i = 1, n = 31;
  5.     while(n<=40)
  6.     {
  7.         while(i<=100){
  8.             printf("%d X %d = %d\n", n, i, n*i);
  9.             i = i + 1;
  10.         }
  11.         printf("\n");
  12.         n = n + 1;
  13.         i = 1;
  14.     }
  15. }

এখানে প্রথমেই আমরা n এবং i এর মানটা ঠিক করে দিয়েছি 31 এবং 1। তারপর প্রথমে একটা লুপ চালিয়েছি যেটা যতক্ষণ n এর মান 40 এর ছোট অথবা সমান থাকবে, ততক্ষণ চলবে। তারপরেই আমরা আরেকটা লুপে ঢুকে গেছি, যেটা i এর মান যতক্ষণ 100 এর চেয়ে ছোট অথবা সমান, ততক্ষণ চলবে। একটা জিনিস মনে রাখা খুব বেশি গুরুত্বপূর্ণ যে, যখন প্রোগ্রাম কোন একটা লুপে ঢোকে, তখন যতক্ষণ সেই লুপের শর্তটা সত্য আছে, ততক্ষণ কেবল সেটার কাজই করতে থাকে। পুরো প্রোগ্রামে আর কোথায় কী আছে না আছে, সেটা তার দেখার বিষয় না। তাই, যখন আমাদের প্রোগ্রামটা ভেতরের লুপ চালানো শুরু করবে, তখন যতক্ষণ i এর মান 100 এর ছোট বা সমান ততক্ষণ লুপটা ঘুরঘুর করে ঘুরতেই থাকবে। এই লুপ থেকে প্রোগ্রাম তখনই বের হবে, যখন i এর মান 100 এর চেয়ে বড় হয়ে যাবে। ভেতরের লুপ থেকে বের হলেও প্রোগ্রাম কিন্তু এখনও বাইরের লুপ থেকে বের হয়নি। বাইরের লুপের কাজ তখনও বাকি। তাই সেখানে যেভাবে বলা আছে সেভাবেই স্ক্রিনে একটা নতুন লাইন যোগ হবে। তারপর n এর মান এক বাড়বে (পরবর্তি নামতা প্রিন্ট করার জন্য)। i এর মান আবারও 1 হিসেবে সেট করা হবে। তারপর চেক করা হবে। যেহেতু, n এর মান এখনও 40 এর চেয়ে ছোট, তাই বাইরের লুপটা আবার পুরো কাজ প্রথম থেকে শুরু করবে। প্রথম থেকে শুরু করতে গিয়েই এটা আবার দ্বিতীয় লুপের মধ্যে ঢুকে যাবে। দ্বিতীয় লুপটা i এর মান 1 থেকে 100 পর্যন্ত বাড়াতে বাড়াতে একটা লাইনই 100 বার প্রিন্ট করে লুপ থেকে বের হবে। তারপর আবার একটা নতুন লাইন প্রিন্ট করবে, n এর মান 1 বাড়াবে, i এর মান হবে 1 তারপর আবার শুরুতে চলে যাবে। আবার ভেতরের লুপের কাজ করবে। এভাবে চলতে থাকবে, যতক্ষণ না n এর মান 41 হয়ে যায় এবং বাইরের লুপের শর্তটা মিথ্যে হয়ে যায়। সেটা হয়ে গেলে, প্রোগ্রাম বাইরের লুপ থেকেও বের হয়ে যাবে এবং প্রোগ্রাম শেষ হবে।

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

লুপ নিয়ে চিন্তা করতে করতে, তুমি হয়তো একটা দারুণ জিনিস খেয়াল করে ফেলেছ। প্রতিটা লুপেরই কিছু কমন অংশ থাকে। একটা লুপের শুরুতেই কিছু ভ্যারিয়েবলের মান ঠিক করে দিতে হয়। এক কাজটা করতে হয়, লুপের শুরুতে একবারই। তারপর লুপে ঢোকার জন্য একটা শর্ত চেক করা হয়। এই শর্তটা যতক্ষণ সত্যি থাকে, ততক্ষণ লুপের কাজ চলতে থাকে। এটা লুপের কাজ প্রতিবার করার আগে একবার করতে হয়। আর প্রতিটা লুপের শেষের দিকে থাকে, তার ভ্যারিয়েবলের মানের কিছু পরিবর্তন যেই পরিবর্তনগুলোর কারণে একট সময় লুপের শর্তটা মিথ্য হয়ে যায় এবং লুপের কাজ শেষ হয়। এই কাজটাও লুপে প্রতিবার করতে হয়। যেহেতু, এই অংশগুলো প্রায় প্রতিটা লুপেই থাকে, তাই এগুলোকে গুছিয়ে রাখতে লুপের আলাদা একটা রূপ আছে যেটাকে বলে for লুপ। for লুপের বিশেষত্বই হচ্ছে, এখানে ভ্যারিয়েবলের মান ঠিক করা, শর্ত এবং ভ্যারিয়েবলের মানের পরিবর্তন এই তিনটা অংশ একই সাথে শুরুতে লিখে ফেলা যায়। তাই, লুপের ভেতরের কেবল কোন কাজটুকু বারবার করতে হবে, সেটা লিখলেই চলে। ফর লুপ কিভাবে ব্যবহার করতে হয়, সেটা বুঝতে আমরা আমাদের আগের প্রোগ্রামটাই ফর লুপ দিয়ে লিখে ফেলি।

  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.     int i, n;
  6.  
  7.     for(= 31; n<=40; n = n + 1){
  8.         for(= 1; i<=100; i = i + 1){
  9.             printf("%d X %d  = %d\n", n, i, n*i);
  10.         }
  11.         printf("\n");
  12.     }
  13. }

একটু খেয়াল করলেই বুঝতে পারবে, আমাদের আগের প্রোগ্রামটায় আমরা যা যা করেছি, এখানেও ঠিক তাই করা হয়েছে কেবল আরও একটু অরগানাইজড পদ্ধতিতে। for লুপের () বন্ধনীর মধ্যে প্রথমে আমরা লিখি লুপ শুরুর সময়ে কোন ভ্যারিয়েবলের মান কী হবে। এই অংশটুকু শুধু একবার কাজ করবে। তারপর একটা ; (সেমিকোলন) দিয়ে লিখি লুপের শর্তটা যেই শর্তটা যতক্ষণ সত্যি থাকবে, ততক্ষন লুপ চলতে থাকবে। তারপর আরও একটা সেমিকোলন দিয়ে লিখি, লুপের শেষ অংশে ভ্যারিয়েবলের মানে যে পরিবর্তন আসবে সেটা। এটাও লুপ প্রতিবার চলার সময় একবার করে কাজ করবে।

তোমাদের আজকের হোমওয়ার্ক হচ্ছে, একটা সংখ্যা স্ক্যান করে, সেই সংখ্যাটা কোন কোন সংখ্যা দ্বারা বিভাজ্য সেগুলো খুঁজে বের করতে হবে। এর জন্য তোমাকে 1 থেকে ওই সংখ্যা পর্যন্ত একটা লুপ চালাতে হবে। তারপর সেই সংখ্যাগুলোর মধ্যে সেগুলো দ্বারা স্ক্যান করা সংখ্যাটাকে ভাগ করলে ভাগশেষ শূন্য হয় ( % অপারেটরের কথা মনে আছে তো?), সেই সংখ্যাগুলো স্ক্রিনে প্রিন্ট করতে হবে।

No comments:

Post a Comment