Thursday, June 28, 2018

ডাটা স্ট্রাকচার - ২ঃ অ্যারের ভিতর বাহির


যদি তোমাকে বলা হয় ৫০ টা নাম্বার একত্রে যোগ করে দাও তাহলে তুমি কি করবে? তুমি কি আগের মত ৫০ টা ভেরিয়েবল ডিক্লেয়ার করে তারপর ইনপুট নিবে? কখনোই না। কারন এটা সময় সাপেক্ষ!

তাহলে আমাদের এমন একটা অবস্থা থাকা দরকার যা দ্বারা আমরা খুব দ্রুত অনেকগুলো ভেরিয়েবল ডিক্লেয়ার করে ফেলতে পারবো! হ্যাঁ, একটা ফিচার আছে যার নাম অ্যারে।  অ্যারে ডিক্লেয়ার করার নিয়মটা হল-  Data_Type variable_name[size]; নীচের উদাহরনটা দেখো-

int value[50];
এটা দেওয়ার সাথে সাথেই কিন্তু ৫০ টা ভেরিয়েবল ডিক্লেয়ার হয়ে গেছে। এই ভেরিয়েবলগুলো হল-
value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7],value[8],value[9].........value[49]
ব্র্যাকেটের ভেতরের সাইজ পরিবর্তন করে এভাবে আমরা যেকোন পরিমান ভেরিয়েবল তৈরী করে ফেলতে পারি। লুপ চালিয়ে খুব সহজভাবেই আমরা এর ভেতরে ডাটা রাখতে পারি এবং ডাটা দেখতে পারি।  নীচের প্রোগ্রামটি খেয়াল করো-

Program - 1: Input 5 numbers in an array and sum it

 #include <stdio.h>  
 int main()  
 {  
   int num[5], i, sum = 0;  
   for(i = 0; i<5; i++)  
   {  
     scanf("%d", &num[i]);  
   }  
   for(i = 0; i<5; i++)  
   {  
     sum+= num[i];  
   }  
   printf("Sum: %d\n", sum);  
   return 0;  
 }  

 Input:   
 10 20 30 40 50   
 Output  
 150  

এখন কথা হল অ্যারে কিভাবে কাজ করে, অ্যারে ডিক্লেয়ার করার সাথে সাথে এতগুলো ভেরিয়েবল তৈরী হয় কিন্তু সেগুলো মেমরিতে কিভাবে থাকে? অ্যারে ব্যবহার জানলেও এটা সম্পর্কে আমাদের বেশিরভাগেরই ধারনা নাই।

অ্যারে সাইজ যতই হোক না কেন সবগুলো মেমরিতে একটা ব্লক  হিসেবে থাকে। মানে অ্যারের  সবগুলো ভেরিয়েবল পাশাপাশি থাকবে বা মেমরিতে পাশাপাশি যায়গা নিবে। আমরা নিচের প্রোগ্রামটিতে অ্যারের মেমরি অ্যাড্রেস প্রিন্ট করে দেখি। তাহলেই বুঝা যাবে। সেই সাথে আমরা নরমাল ভেরিয়েবলের মেমরি অ্যাড্রেস প্রিন্ট করে অ্যারে এবং সাধারন ভেরিয়েবলের মেমরি অ্যাড্রেসের পার্থক্য বুঝার চেষ্টা করবো-

Program - 1: Print the Memory of an array and normal variables 

 #include <stdio.h>  
 int main()  
 {  
   int i, num[10], sum = 0;  
   printf("Memory Address of array: ");  
   for(i = 0; i<10; i++)  
   {  
     printf("%d ", &num[i]);  
   }  
   printf("\n");  
   printf("Memory address of variables: ");  
   printf("%d %d\n", &i, &sum);  
   return 0;  
 }  

 Output:   
 Memory Address of array: 6356708 6356712 6356716 6356720 6356724 6356728 6356732 6356736 6356742 6356744  
 Memory address of variables: 6356748 6356724  

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

অ্যারের এই বৈশিষ্ট্যটা কাজে লাগিয়ে আমরা ইন্ডেক্সিং এবং & ছাড়াই ডাটা ইনপুট এবং আউটপুট দেখাতে পারি। নীচের প্রোগ্রামটি খেয়াল করো- 

Program - 3: Input 10 numbers in an array and print it. Don't use any ampersand or array indexing 

 #include <stdio.h>  
 int main()  
 {  
   int i, num[10], sum = 0;  
   int *ptr = num;  
   for(i = 0; i<10; i++)  
   {  
     scanf("%d", ptr);  
     ptr++;  
   }  
   ptr = num;  
   for(i = 0; i<10; i++)  
   {  
     printf("%d ", *ptr);  
     ptr++;  
   }  
   return 0;  
 }  

 INPUT   
 10 20 30 40 50 60 70 80 90 100  
 OUTPUT  
 10 20 30 40 50 60 70 80 90 100  

এখন প্রশ্ন হল এটা আসলে কিভাবে কাজ করে? মনে করো তোমার বাড়ির পাশে সিরিয়ালি আরো ৯ টি বাড়ি আছে। তোমার বাড়িটা সবার প্রথমে। গনু মোল্লা নামের একজন লোক আছে যে তোমার বাসাটা চিনে।  এখন ধরা যাক ট্রাম্প নামক একজন ভিজিট করতে আসলো। কিন্তু ট্রাম্প দ্বিধায় পড়ে গেলেন। কোথা থেকে শুরু করবেন। ট্রাম্প আগে থেকেই জানতো সবগুলো বাড়ি সিরিয়ালি আছে এবং বুঝতে পারলেন প্রথম বাড়ির অ্যাড্রেস জানতে পারলেই খেলা ফাইনাল। তারপর ট্রাম্প নিক্কি হ্যালির পরামর্শক্রমে গনু মোল্লার কাছে গিয়ে প্রথম অ্যাড্রেসটা জানতে গেলেন। কারন তিনি জানেন গনু মোল্লা কখনো মিথ্যা কথা বলেনা। তারপর গনু মোল্লা সুন্দর করে তোমার বাড়ির অ্যাড্রেস টা বলে দিলো। ব্যাস খেলা শুরু হয়ে গেলো। ট্রাম্প সাহেব এক এক করে সবার বাড়ি ভিজিট করে ফেললেন।

এখানে num হল সেই গনু মোল্লা এবং ptr  হল সেই ট্রাম্প সাহেব। ট্রাম্প সাহেব তোমার এলাকায় আসার সাথে সাথেই গনু মোল্লা ptr = num দিয়ে জানিয়ে দিলো তোমার বাসার অ্যাড্রেস। তারপর কি হল সেটা তো তুমিই জানো।

একদম শুরুতে num এবং ptr প্রথম অবস্থানে থাকে এবং  ptr প্রতিবার এক এক করে  বাড়াতে বাড়াতে সবগুলো অ্যাড্রেসে যেতে পারছে এবং সেই পার্টিকুলার অ্যাড্রেসের ডাটা নিতে বা রাখতে পারছে। একে পয়েন্টিং বলা হয় আর ptr বা num কে পয়েন্টার বলা হয়। এভাবে একটা লিস্ট বা অ্যারের শেষ পর্যন্ত সে ট্রাভেল করতে পারে। এভাবেই অ্যারে কাজ করে। আশাকরি বুঝতে সমস্যা হয়নাই।

প্র্যাক্টিস প্রব্লেমঃ
১। ট্রাম্প যদি গনু মোল্লাকে নিয়েই সবগুলো বাড়িতে যেতেন তাহলে কি সমস্যা হতো, উত্তর জানাও কমেন্টে।