Thursday, May 9, 2013

[ সি প্রোগ্রামিং :- অধ্যায় তিন ] কন্ডিশনাল লজিক ।


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

#include <stdio.h>   
 int main()   
 {   
     int n;   
     n = 10;   
     if(n >= 0) {   
         printf("The number is positive\n");   
     }   
     else {   
         printf("The number is negative\n");   
     }   
     return 0;   
 }  
 প্রোগ্রাম: ৩.১  

ওপরের প্রোগ্রামটির কাজ কী ? n –এর বিভিন্ন মান(যেমন: 0, -10, -2, 5, 955, 111 ইত্যাদি) বসিয়ে আপনারা প্রোগ্রামটি চালান । দেখা যাচ্ছে যে, এর কাজ হচ্ছে n ধনাত্বক(positive) না ঋণাত্বক(negative) সেটি নির্ণয় করা । কোন সংখ্যা ধনাত্বক হতে গেলে একটি শর্ত পূরণ করতে হয় । সেটি হচ্ছে তাকে শূন্যের সমান বা তার চেয়ে বড় হতে হয় । তাহলে আমাদের লজিকটি দাঁড়াচ্ছে এ রকম যে, n যদি শূন্যের সমান বা বড় হয় তবে n ধনাত্বক, আর তা না হলে n ঋণাত্বক । এই ব্যাপারটি সি ল্যাঙ্গুয়েজে প্রকাশ করতে হয় if এবং তার সঙ্গে else ব্যবহার করে । if  এর ভেতর একটি শর্ত (কন্ডিশন) লিখে দিতে হয় যা সত্যি হলেই কেবল তার ভেতরের অংশের কাজ হয় (মানে if –এর পর যে দ্বিতীয় বন্ধনী {} ব্যবহার করা হয়েছে তার ভেতরের সব কাজ) ।আর কন্ডিশনটা লিখতে হয় প্রথম বন্ধনীর ভেতরে । if এর ভেতরে যেই কন্ডিশনটা আছে সেটি যদি মিথ্যা হয়, তবে else –এর ভেতরের (দ্বিতীয় বন্ধনীর ভেতরে) অংশের কাজ হয় । সব প্রোগ্রামিং ল্যাঙ্গুয়েজেই এটি আছে, তবে লিখার ধরণ হয়তো আলাদা ।

এখন আমাদের দেখতে হবে, কন্ডিশনগুলো কীভাবে লিখতে হবে ? আপনারা এতক্ষণে জেনে গেছেন যে ‘বড় কিংবা সমান’ এই তুলনার জন্য >= চিহ্ন ব্যবহার হয় । ‘ছোট কিংবা সমান’ এর জন্য ব্যবহার করে <= চিহ্ন । দুটি সংখ্যা একটি আরেকটির সমান কি না সেটি পরীক্ষার জন্য ব্যবহার করে == চিহ্ন (লক্ষ করুন এখানে দুটি সমান চিহ্ন আছে )। শুরুর দিকে অনেকেই সমান কি না পরীক্ষার জন্য ভুল করে = (একটি সমান চিহ্ন যা দিয়ে আসলে কোনো ভেরিয়েবলে কোনোকিছু অ্যাসাইন করা হয়) ব্যবহার করে বিপদে পড়ে যায়) । দুটি সংখ্যা পরস্পর অসমান কি না, এটি পরীক্ষার জন্য != চিহ্ন ব্যবহার করে । আর ছোট কিংবা বড় পরীক্ষার জন্য < আর > চিহ্ন ব্যবহার করতে হয় । আরও ব্যাপার-স্যাপার আছে । একেবারে সব না শিখে চলুন আস্তে আস্তে প্রোগ্রাম লিখে শেখা যাক । এখানে ইন্ডেন্টেশনের ব্যাপারটিও কিন্তু খেয়াল করুন । if কিংবা else –এর ভেতরের ব্লকের সব লাইন কিন্তু if বা else যেখানে শুরু, তার চার ঘর (চারটি স্পেস) ডান থেকে শুরু হয়েছে।
আমরা ওপরের প্রোগ্রামটি এভাবেও লিখতে পারতাম:

#include <stdio.h>   
 int main()   
 {   
     int n;     
     n = 10;   
     if(n < 0) {   
         printf("The number is negative\n");   
     }   
     else {   
         printf("The number is positive\n");   
     }   
     return 0;   
 }  
 প্রোগ্রাম: ৩.২  
এখানে আমরা প্রথমে পরীক্ষা করেছি যে n শূন্যের চেয়ে ছোট কি না । যদি ছোট হয়, তবে n নেগেটিভ; আর সেটি না হলে (সেটি না হওয়া মানে n অবশ্যই শূন্যের সমান বা বড়) n পজিটিভ ।

আপনাদের মাঝে যারা একটু খুঁতখুঁতে স্বভাবের, তারা নিশ্চয়ই ভাবছেন যে শূন্য তো আসলে পজিটিভ বা নেগেটিভ কোনোটাই না । শূন্যের চেয়ে বড় সব সংখ্যা হচ্ছে পজিটিভ আর ছোট সব সংখ্যা হচ্ছে নেগেটিভ । কম্পিউটারকে সেটি বোঝাতে গেলে আমরা নিচের প্রোগ্রামটি লিখতে পারি:

#include <stdio.h>   
 int main()   
 {   
     int n = 10;    
     if(n < 0) {   
         printf("The number is negative\n");   
     }   
     else if (n > 0) {   
         printf("The number is positive\n");   
     }   
     else if (n == 0) {  
         printf("The number is zero!\n");   
     }   
     return 0;   
 }  
 প্রোগ্রাম: ৩.৩  

প্রোগ্রামটি একটু ব্যাখ্যা করা যাক:-
If(n < 0) এখানে আমরা প্রথমে পরীক্ষা করেছি n শূন্যের চেয়ে ছোট কি না । ছোট হলে তো কথাই নেই । আমরা বলে দিচ্ছি যে সংখ্যাটি নেগেটিভ । else if(n > 0) আর যদি ছোট না হয়, তবে n শূন্যের চেয়ে বড় কি না সেটি পরীক্ষা করেছি else if(n > 0) । এই শর্ত সত্যি হলে সংখ্যাটি পজিটিভ ।
আর n > 0 ও যদি সত্যি না হয় তবে কোন শর্তটি বাদ রইল ? দুটি সমান কি না সেটি পরীক্ষা করা else if(n == 0) । তাহলে আমরা পরীক্ষা করেছি যে n শূন্যের সমান কি না এবং সমান হলে বলে দিচ্ছি যে এটি শূন্য।

দুটি সংখ্যা তুলনা করার সময় প্রথমটা যদি দ্বিতীয়টির চেয়ে বড় না হয়, ছোটও না হয়, তবে তারা অবশ্যই সমান । তাই তৃতীয় কন্ডিশনটা আসলে আমাদের দরকার নেই । আমরা প্রথম দুটি কন্ডিশন মিথ্যা হলেই বলে দিতে পারি যে n-এর মান শূন্য ।

 #include <stdio.h>   
 int main()   
 {   
     int n = 10;    
     if(n < 0) {   
         printf("The number is negative\n");   
     }   
     else if (n > 0) {   
         printf("The number is positive\n");   
     }   
     else {   
         printf("The number is zero!\n");   
     }   
     return 0;   
 }  
 প্রোগ্রাম: ৩.৪  

আবার সব সময় যে if ব্যবহার করলেই সঙ্গে else কিংবা else if ব্যবহার করতে হবে, এমন কোনো কথা নেই ।   নিচের প্রোগ্রামটি দেখুন:

 #include <stdio.h>   
 int main()   
 {   
     int number = 12;   
     if(number > 10) {   
         printf("The number is greater than ten\n");   
     }   
     return 0;  
 }  
 প্রোগ্রাম: ৩.৫ 

এখানে কেবল দেখা হচ্ছে যে সংখ্যাটির মান কি দশের চেয়ে বড় কি না ।

নিচের প্রোগ্রামটি দেখে বলুন তো আউটপুট কি হবে ?

#include <stdio.h>  
 int main()  
 {  
     int n = 10;  
     if (n < 30) {  
         printf("n is less than 30.\n");  
     }  
     else if(n < 50) {  
         printf("n is less than 50.\n");  
     }  
     return 0;  
 }  
 প্রোগ্রাম: ৩.৬  

আউটপুট হবে: n is less than 30 যদিও else if(n < 50) এটিও সত্য কিন্তু যেহেতু if(n < 30) সত্য হয়ে গেছে, তাই এর সঙ্গে বাকি যত else if কিংবা else থাকবে , সেগুলো আর পরীক্ষা করা হবে না । এখন আপনারা নিশ্চয়ই নিচের প্রোগ্রামটির আউটপুট বলতে পারবেন ।

#include <stdio.h>  

 int main()  

 {  

     int n = 10;  

     if (n < 30) {  

         printf("n is less than 30.\n");  

     }  

     if(n < 50) {  

         printf("n is less than 50.\n");  

     }  

     return 0;  

 }  

 প্রোগ্রাম: ৩.৭  

এখন আমরা আরেকটি প্রোগ্রাম লিখব । কোনো সংখ্যা জোড় না বিজোড় সেটি নির্ণয় করার প্রোগ্রাম । কোনো সংখ্যা জোড় কি না সেটি বোঝার উপায় হচ্ছে সংখ্যাটিকে 2 দিয়ে ভাগ করা । যদি ভাগশেষ শূন্য হয়, তবে সংখ্যাটি জোড়; আর ভাগশেষ শূন্য না হয়ে এক হলে সেটি বিজোড় । সি ল্যাঙ্গুয়েজে ভাগশেষ বের করার জন্য মডুলাস অপারেটর (modulus operator) আছে, যেটাকে '%' চিহ্ন দিয়ে প্রকাশ করা হয় । তাহলে আর চিন্তা নেই ।

শুরুতে একটি সংখ্যা নেব: int number;
এবারে number –এর জন্য একটি মান ঠিক করি: number = 5;
এখন number কে 2 দিয়ে ভাগ করলে যে ভাগশেষ পাব সেটি বের করি: remainder = number % 2; এখন if –এর সাহায্যে remainder –এর মান পরীক্ষা করে আমরা সিদ্ধান্তে পৌঁছে যেতে পারি । remainder –এর কেবল দুটি মানই সম্ভব- 0 আর 1 । পুরো প্রোগ্রামটি লিখে ফেলি:

#include <stdio.h>   
 int main()   
 {   
     int number, remainder;   
     number = 5;   
     remainder = number % 2;   
     if(remainder == 0) {   
         printf("The number is even\n");   
     }   
     else {   
         printf("The number is odd\n");   
     }   
     return 0;   
 }  
 প্রোগ্রাম: ৩.৮  

প্রোগ্রামটি remainder ভেরিয়েবল ব্যবহার না করেও লেখা যায়:

#include <stdio.h>   
 int main()   
 {   
     int number = 9;   
     if(number % 2 == 0) {   
         printf("The number is even\n");   
     }   
     else {   
         printf("The number is odd\n");   
     }   
     return 0;   
 }  
 প্রোগ্রাম: ৩.৯

আচ্ছা, আমাদের যদি কেবল জোড় সংখ্যা নির্ণয় করতে হতো, তাহলে আমরা কী করতাম ? else ব্লকটা বাদ দিয়ে দিতাম ।

আপনাদের জন্য এখন একটি ছোট্র পরীক্ষা । মডুলাস অপারেটর ব্যবহার না করে ভাগশেষ বের করতে পারবেন ?
একবার করে গুণ, ভাগ ও বিয়োগ (*,/,-) ব্যবহার করে কিন্তু কাজটি করা যায় । আপনারা সেটি করার চেষ্টা করতে পারেন ।

এবার আরেকটি প্রোগ্রাম দেখা যাক । কোনো একটি অক্ষর ছোট হাতের(small letter বা lower case latter) নাকি বড় হাতের (capital letter বা upon case letter), সেটি বের করতে হবে । এর জন্য সবচেয়ে সহজ সমাধানটা হতে পারে এই রকম যে আমরা একটি character টাইপের ভেরিয়েবলের ভেতরে অক্ষরটা রাখতে পারি । তারপর একে একে সেটিকে 26 টি lower case letter এবং 26 টি upper case letter –এর সঙ্গে তুলনা করে দেখতে পারি । যখনই মিলে যাবে, তখনই বলে দেওয়া যায়, অক্ষরটা কোন ধরনের ।

char ch = 'p';  
 if (ch == 'a')  
 {  
     printf("%c is lower case\n", ch);  
 }  
 else if (ch == 'A')  
 {  
     printf("%c is upper case\n", ch);  
 }  
 else if (ch == 'b')  
 {  
     printf("%c is lower case\n", ch);  
 }  
 else if (ch == 'B')  
 {  
     printf("%c is upper case\n", ch);  
 }    
 else if (ch == 'c')  
 {  
     printf("%c is lower case\n", ch);  
 }  
 else if (ch == 'C')  
 {  
     printf("%c is upper case\n", ch);  
 }  
………..এভাবে চলতে থাকবে ।

কিন্তু এই সমস্যা সমাধান করার জন্য এত কোড লিখার কোনো দরকার নেই । এটি সহজে করার জন্য আমাদের জানতে হবে এন্ড অপারেটরের (AND operator) ব্যবহার । সি ল্যাঙ্গুয়েজে একে '&&' দ্বারা প্রকাশ করা হয় । নিচের কোডটি দেখলে আপনারা এর কাজটি বুঝে যাবেন ।

#include <stdio.h>  
 int main()  
 {  
     char ch = 'W';  
     if(ch >= 'a' && ch <= 'z') {  
         printf("%c is lower case\n", ch);  
     }  
     if(ch >= 'A' && ch <= 'Z') {  
         printf("%c is upper case\n", ch);  
     }  
     return 0;  
 }  
 প্রোগ্রাম: ৩.১০  

'&&' -এর বা পাশে একটি কন্ডিশন এবং ডান পাশে একটি কন্ডিশন থাকবে, এবং দুটি কন্ডিশন সত্য হলেই সম্পূর্ণ কন্ডিশনটা সত্য হবে । ch >= 'a' && ch <= 'z' এটি পুরোটা একটি কন্ডিশন । এখন && -এর বাঁ দিকে একটি কন্ডিশন আছে ch >= 'a' এবং ডান দিকে আরেকটি কন্ডিশন ch <= 'z' । দুটি কন্ডিশনই যদি সত্য হয়, তবে পুরো কন্ডিশনটা সত্য হবে । এখন কম্পিউটার প্রতিটি অক্ষর বোঝার জন্য যেই কোড ব্যবহার করে তাতে a-এর চেয়ে b-এর মান এক বেশি, b-এর চেয়ে c এর মান এক বেশি, c-এর চেয়ে d এর মান এক বেশি, …… এরকম । তাই কোনো অক্ষর lower case হলে সেটি অব্যশই 'a' এর সমান কিংবা বড় হতে হবে । আবার সেটি 'z' এর সমান কিংবা ছোট হতে হবে । একইভাবে A-এর চেয়ে B-এর মান এক বেশি, B-এর চেয়ে C এর মান এক বেশি …..এরকম । তাই কোনো ক্যারেক্টারের মান 'A' থেকে 'Z' এর মধ্যে হলে আমরা বলতে পারি যে সেটি upper case । 'A' –এর সমান কিংবা বড় হতে হবে এবং 'Z' এর সমান কিংবা ছোট হতে হবে । আরেকটি ব্যাপার । দ্বিতীয় if –এর আগে else ব্যবহার করা উচিত । তাহলে কম্পাইলার প্রথম if –এর ভেতরের শর্ত সত্য হলে আর পরের if –এর কন্ডিশন পরীক্ষা করবে না । তাতে সময় বাঁচবে ।

#include <stdio.h>  

 int main()  
 {  
     char ch = 'k';  
     if(ch >= 'a' && ch <= 'z') {  
         printf("%c is lower case\n", ch);  
     }  
     else if(ch >= 'A' && ch <= 'Z') {  
         printf("%c is upper case\n", ch);  
     }  
     return 0;  
 }  
 প্রোগ্রাম: ৩.১১  

আশা করি, আপনারা '&&' –এর ব্যবহার বুঝে গেছেন ।
এখন আরেকটি অপারেটরের ব্যবহার দেখব । সেটি হচ্ছে অর (oR) । একে প্রকাশ করা হয় '||' চিহ্ন দিয়ে (পরপর দুটি |) । '&&' এর ক্ষেত্রে যেমন দুটি শর্ত সত্য হলেই সম্পূর্ণ শর্ত সত্য হয়, '||' এর ক্ষেত্রে যেকোনো এক পাশের শর্ত সত্য হলেই সম্পূর্ণ শর্ত সত্য হয় ।
নিচের প্রোগ্রামটির আউটপুট কী হবে ? কোড দেখে বলতে না পারলে প্রোগ্র্রামটি চালান ।

#include <stdio.h>  
 int main()  
 {  
     int num = 5;  
     if(num >= 1 || num <= 10) {  
         printf("yes\n");  
     }  
     else {  
         printf("no\n");  
     }  
     return 0;  
 }  
 প্রোগ্রাম: ৩.১২  
এটির আউটপুট হবে yes । এখন num –এর মান 50 করে দিন । আউটপুট কী হবে ?

এবারেও আউটপুট yes ই হবে । কারণ num এর মান 50 হলে, প্রথম শর্তটি সত্য হবে (num >= 1) আর দ্বিতীয় শর্তটি (n <= 10) মিথ্যা হবে । তবে আমরা যেহেতু দুটি শর্তের মাঝে '||' ব্যবহার করেছি, তাই যেকোনো একটি শর্ত সত্য হলেই সম্পূর্ণ শর্তটি সত্য হবে । এখন আরও একটি সমস্যা । কোনো অক্ষর vowel নাকি consonant, সেটি নির্ণয় করতে হবে । আমরা জানি, vowel গুলো হচ্ছে a, e, i, o, u, । এখন কোনো ক্যারেক্টার এই পাঁচটির মধ্যে পড়ে কিনা সেটি নির্ণয় করার জন্য যদি আমরা এমন শর্ত দিই : ch >= 'a' && ch <= 'u' তাহলে কিন্তু হবে না । কারণ তাহলে a থেকে u পর্যন্ত সব অক্ষরের জন্যই শর্তটি সত্যি হবে কিন্তু আমাদের দরকার নিদিষ্ট কিছু অক্ষর । তাই শর্তটি আমরা এভাবে লিখতে পারি :

if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {  
     printf("%c is vowel\n", ch);  
 }  
 else {  
     printf("%c is consonant\n", ch);  
 }  

তাহলে এবার সম্পূর্ণ প্রোগ্রামটি আপনারা লিখে ফেলতে পারেন ।
 

1 comment:

  1. আপনারা যারা সি প্রোগ্রামিং শিখছেন তারা প্রতিটি অধ্যায়ের শেষ করতে পারলে সেই অধ্যায়ের শেষে একটি দুটি করে কম্মেন্ট দিবেন তাহলে নতুনরা অনেক উৎসাহিত হবে । ধন্যবাদ ।

    ReplyDelete