সি/সি++ প্রোগ্রামিং টিউটোরিয়াল (পর্ব ১৩) পয়েন্টার (২)

0
298

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

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

পয়েন্টার

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

ভেরিয়েবলের অ্যাড্রেস

সি-তে ভেরিয়েবল নিয়ে কাজ করার জন্য অ্যাড্রেস অপারেটর ব্যবহার করা হয় এবং একে ‘&’ দিয়ে প্রকাশ করা হয়। এই অপারেটরটি শুধু ভেরিয়েবলের সাথে ব্যবহার করা যায়। যেমন : বলতে একটি ভেরিয়েবল বোঝাবে, কিন্তুী্ দিয়ে ওই ভেরিয়েবলের অ্যাড্রেস বোঝাবে। এমনকি সি-তেও মাঝে মাঝে ভেরিয়েবলের অ্যাড্রেস উলেস্নখ করে দিতে হয়। এ কারণেই কোনো ইনপুট নেয়ার সময় scanf(‘‘%d’’,&x) ফাংশনের ভেতরে ব্যবহার করা হয়। অর্থাৎ এখানে প্রোগ্রামকে বলে দেয়া হয়, ইনপুট নিয়ে সেটাী-এর অ্যাড্রেসে রেখে দাও। একইভাবে কোনো ভেরিয়েবলের অ্যাড্রেস প্রিন্ট করা সম্ভব।

সাধারণত ভেরিয়েবল প্রিন্ট করার সময় সাধারণভাবে ভেরিয়েবলের নাম লেখা হয়। কিন্তু অ্যাড্রেস প্রিন্ট করাতে চাইলে printf(‘‘%d’’,&x) এভাবে লিখতে হবে। মনে রাখতে হবে, এভাবে প্রিন্টের কমান্ড লিখলেী-এর মান প্রিন্ট হবে না, বরং তার অ্যাড্রেস প্রিন্ট হবে। তবে এ অ্যাড্রেস হেক্সাডেসিমেল নাম্বারে প্রিন্ট হবে। কমপিউটার সাধারণত হেক্সাডেসিমেলেই ইনপুট নেয় এবং আউটপুট দেয়। কিন্তু প্রসেসর যখন হিসাব করে তখন বাইনারিতে করে। আবার আউটপুট যদি ইউজার ডেসিমেলে চায়, তাহলে ডেসিমেলেই দেখানো হয়। কোনো নাম্বার হেক্সাডেসিমেলে আছে কিনা, তা চেনার সহজ উপায় হলো নাম্বার যদি হেক্সাডেসিমেল হয় তাহলে তার শেষে য থাকবে।

পয়েন্টার ভেরিয়েবল

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

int *gpa; A_ev int* gpa;
char *grade; A_ev char* grade;
double *cgpa; A_ev double* cgpa;

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

একটি হলো ডাটা টাইপের পয়েন্টার। অর্থাৎ ডিক্লেয়ারেশনের প্রথম অংশ নির্দেশ করে পয়েন্টারটি কোন ধরনের ডাটা টাইপকে পয়েন্ট করতে সক্ষম হবে। আর পরের অংশ হলো পয়েন্টারের নাম। এটি সাধারণ ভেরিয়েবলের মতো যেকোনো নাম হতে পারে।লক্ষণীয়,পয়েন্টারে সত্যিকার অর্থে কোনো ডাটা টাইপ নেই। আমরা জানি, একেক টাইপের ডাটা একেক ধরনের মান ধারণ করতে পারে। যেমন : ক্যারেক্টার টাইপের ভেরিয়েবল সর্বোচ্চ ২৫৫ পর্যন্ত মান ধারণ করতে পারে। আবার ইন্টিজার সর্বোচ্চ ৩২৭৬৭ পর্যন্ত ধারণ করতে পার। পয়েন্টারের ক্ষেত্রে এ ধরনের কোনো বিষয় নেই যে ইন্টিজার টাইপের পয়েন্টার একরকম, আবার ক্যারেক্টার টাইপের পয়েন্টার আরেকরকম মান ধারণ করতে পারে। সব পয়েন্টারই একই ধরনের মান ধারণ করতে পারে। একটি ইন্টিজার টাইপের পয়েন্টার যে পর্যন্ত সংখ্যা ধারণ করতে পারে, ক্যারেক্টার টাইপের পয়েন্টারও একই সংখ্যা ধারণ করতে পারে। শুধু পার্থক্য হলো, সাধারণ ভেরিয়েবলের ক্ষেত্রে ভিন্ন টাইপ মানে হলো ভেরিয়েবলের লিমিট ভিন্ন হবে, আর পয়েন্টারের ক্ষেত্রে ভিন্ন টাইপ মানে হলো ভিন্ন টাইপের ভেরিয়েবলকে পয়েন্ট করবে।

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

সাধারণ ভেরিয়েবল এবং পয়েন্টার দুটোর কাজ একই। তা হলো ডাটা রাখা। একজন ডাটা রাখে আর আরেকজন ডাটার অ্যাড্রেস রাখে। তাই একই স্কোপের মাঝে ভেরিয়েবল এবং পয়েন্টার দুটোর নাম একই হতে পারবে না। সাধারণ ভেরিয়েবল এবং পয়েন্টার ডিক্লেয়ার করার নিয়ম সম্পূর্ণ এক। তাই সাধারণ ভেরিয়েবলকে যেমন একসাথে ডিক্লেয়ার করা যায়, তেমনি পয়েন্টারকেও একসাথে ডিক্লেয়ার করা যায়। যেমন : int x,y,*z; এখানে তিনটি ইন্টিজার টাইপের ভেরিয়েবল ডিক্লেয়ার করা হয়েছে। এর প্রথম দুটি সাধারণ ভেরিয়েবল এবং তৃতীয়টি পয়েন্টার ভেরিয়েবল।পয়েন্টারের মূল কাজ মেমরির অ্যাড্রেস ধারণ করা।

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

একটি উত্তর ত্যাগ