প্রোগ্রামিং সংক্রান্ত নানান বই ঘরে বসে অনলাইনে অর্ডার করতে ক্লিক করুন এখানে

বাংলা ভাষায় পাইথন দিয়ে প্রোগ্রামিং শেখার ফ্রি বই - http://pybook.subeen.com

প্রোগ্রামিং লেবেলটি সহ পোস্টগুলি দেখানো হচ্ছে৷ সকল পোস্ট দেখান
প্রোগ্রামিং লেবেলটি সহ পোস্টগুলি দেখানো হচ্ছে৷ সকল পোস্ট দেখান

পয়েন্টার পরিচিতি

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

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

প্রোগ্রামটি রান করলে আউপুট দেখবে এমন :
Value of x is 10
Address of x is 0x0060FF0C

তাহলে আমরা দেখতে পাচ্ছি x-এর একটি মান আছে, আর আছে অ্যাড্রেস বা ঠিকানা। আমরা আগের অধ্যায়েই ব্যাপারটি জেনেছি। এখন আমরা যদি ভ্যারিয়েবলের মান নিয়ে কাজ করার বদলে তার ঠিকানা নিয়ে কাজ করতাম, তাহলে কেমন হতো? তোমাদের মনে প্রশ্ন আসতে পারে, ভ্যারিয়েবলের ঠিকানা নিয়ে কাজ করার দরকার কী? এতদিন পর্যন্ত তো মান দিয়েই ঠিকঠাক প্রোগ্রাম লিখে এসেছি। আসলে দরকার আছে, কিন্তু বিষয়গুলো ঠিক এখনই বুঝবে না, পরে বুঝবে। আমি এখন বোঝানোর চেষ্টা করলে তোমরা ভুল বুঝবে, তাই ভুল বোঝার চেয়ে না বোঝা ভালো। আপাতত জেনে রাখো যে, এটি একটি গুরুত্বপূর্ণ বিষয়।

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



প্রোগ্রামটি রান করলে এরকম আউটপুট পাবে:
10
Value of p is 0x0060FF08

লক্ষ কর, int *p; স্টেটমেন্ট ব্যবহার করে আমরা একটি ইন্টিজার টাইপের পয়েন্টার ডিক্লেয়ার করলাম যার নাম p। p-তে আমরা ইন্টিজার টাইপের ভ্যারিয়েবলের ঠিকানা রাখতে পারব। সেটিই আমরা করেছি p = &x; লাইনে। x নামক ইন্টিজার ভ্যারিয়েবলের ঠিকানা আমরা p-তে রাখলাম। এখন p-এর মান প্রিন্ট করলে আমরা x-এর ঠিকানা পাব। আর x-এর মান পাওয়ার জন্য কী ব্যবস্থা? সেটি হচ্ছে *p প্রিন্ট করা। ওপরের উদাহরণটি যদি তোমরা টাইপ করে থাক, তাহলে তোমার কম্পিউটার স্ক্রিনের দিকে আবার লক্ষ কর এবং বিষয়টি তোমার কাছে পরিষ্কার হয়েছে কি না দেখো, আর যারা প্রোগ্রাম নিজে টাইপ করে কম্পাইল ও রান করছ না, তাদের জন্য সমবেদনা রইল।
এখন আমরা একটি পরীক্ষামূলক প্রোগ্রাম লিখব। আমি তো একটু আগে বলেছি যে ভ্যারিয়েবল যে টাইপের হবে, পয়েন্টারও সে টাইপের হতে হবে। সেটি না হলে কী হবে? বেশি চিন্তা না করে প্রোগ্রাম লিখে দেখি।

প্রোগ্রাম কম্পাইল করতে গেলে কম্পাইলার তোমাকে এই বার্তা দিয়ে সতর্ক করে দিবে :
warning: incompatible pointer types assigning to 'int *' from 'double *' 
অথবা এরকম এরর দিবে:
error: cannot convert 'double*' to 'int*' in assignment

এখন আমরা আরেকটি কাজ করব। একটি ইন্টিজার টাইপের পয়েন্টারে ইন্টিজার ভ্যারিয়েবলের ঠিকানা রাখব, তারপর পয়েন্টারের মান পরিবর্তন করে দিব। তাহলে দেখা যাবে মূল ভ্যারিয়েবলের মান পরিবর্তন হয়ে গিয়েছে।

আউটপুট হবে এরকম:
Value of x: 10
Value of x: 20
Address of x: 0x0060FF08
Value of p: 0x0060FF08

আর হ্যাঁ, অ্যাড্রেস কিন্তু তোমার কম্পিউটারে অন্যরকম আসবে, তবে দুটি অ্যাড্রেস সমান হবে।
তো এরকম কেন হলো? x-এর মান কেন পরিবর্তিত হলো? এমনটিই তো হওয়ার কথা। আমি তো p পয়েন্টারে x-এর ঠিকানা রেখেছি আর তারপর *p = 20; (পড়ব content of p = 20) লিখেছি, অর্থাৎ আমি p পয়েন্টারে যেই ঠিকানা আছে, সেই ঠিকানায় যেই ভ্যারিয়েবল আছে, সেখানে 20 অ্যাসাইন করেছি। তাই x-এর মান এখন 20। আমি যদি তোমাকে বলি যে, দ্বিমিক কম্পিউটিংয়ের অফিসে একটি বই পৌঁছে দিতে, তাহলে তুমি সেটি করতে পারবে কারণ তুমি হয়তো নিজেই সেই অফিস চেন কিংবা তোমার বন্ধুদের কাছে খোঁজখবর নিয়ে অফিসটি চিনে নিতে পারবে। আর আমি যদি তোমাকে বলি ফ্ল্যাট নম্বর w, বাসা নম্বর x, সড়ক নম্বর y, এলাকার নাম z, তাহলেও কিন্তু তুমি সঠিক জায়গায় যেতে পারবে, এটি দ্বিমিকের অফিস কি না সেটি তোমার না জানলেও চলবে।

আরেকটি উদাহরণ দিই। ধরা যাক, তোমার ক্লাসে রোল নম্বর 25। যখন শিক্ষক তোমার নাম ধরে ডাক দেন, তখন তুমি দাঁড়াও। আবার তোমার রোল নম্বর ধরে ডাক দিলেও তুমি দাঁড়িয়ে যাও। তাহলে তুমি যদি কোনো ভ্যারিয়েবল হও, তোমার ঠিকানা হচ্ছে তোমার রোল নম্বর। বুঝতে পারলে?

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


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

বিশেষ দ্রষ্টব্য: এই লেখাটি "কম্পিউটার প্রোগ্রামিং দ্বিতীয় খণ্ড" বইয়ের তৃতীয় অধ্যায় (পয়েন্টার)-এর অংশবিশেষ। 
নিচের ছবিতে ক্লিক করে বইটি সম্পর্কে আরো জানা যাবে :


কম্পিউটারের মেমোরি

আমরা সচরাচর যেসব কম্পিউটার দেখি (যেমন: ডেস্কটপ, ল্যাপটপ), সেসব কম্পিউটারে থাকে –
  • ইনপুট নেওয়ার যন্ত্র। যেমন মাউস, কিবোর্ড। এদের কাজ হচ্ছে কম্পিউটারে ইনপুট নেওয়ার ব্যবস্থা করা। 
  • আউটপুট দেওয়ার যন্ত্র। যেমন মনিটর, প্রিন্টার। এদের কাজ হচ্ছে আউটপুট দেখানোর ব্যবস্থা করা। 
  • তথ্য ধারণ করার যন্ত্র বা স্টোরেজ ডিভাইস। যেমন পেন ড্রাইভ, হার্ড ডিস্ক, র‍্যাম। এদের কাজ হচ্ছে স্থায়ীভাবে বা অস্থায়ীভাবে তথ্য সংরক্ষণ করা। 
  • কেন্দ্রীয় প্রক্রিয়াকরণ অংশ বা সেন্ট্রাল প্রসেসিং ইউনিট (Central Processing Unit), সংক্ষেপে সিপিইউ (CPU)। যেমন মাইক্রোপ্রসেসর। এর কাজ হচ্ছে বিভিন্ন হিসাব-নিকাশ করা।
কম্পিউটারের মেমোরির কী দরকার? প্রসেস করতে পারলেই তো হয়ে যায়। - এরকম চিন্তা তোমরা অনেকেই কর। কিন্তু কম্পিউটার যে প্রসেস করবে, কী প্রসেস করবে? নিশ্চয়ই ডেটা। আর সেই ডেটা কোথাও তো রাখা দরকার, নইলে কম্পিউটার মহাশয় মনে রাখবে কী করে যে তাকে কোন জিনিসটি প্রসেস করতে হবে?

বিট ও বাইট
তোমরা তো ইতিমধ্যেই জেনে গিয়েছ যে কম্পিউটার যে হিসাব-নিকাশ করে, সেগুলো যত বড় বড় হিসাবই হোক না কেন, শেষ পর্যন্ত কম্পিউটার কেবল শূন্য আর এক ব্যবহার করে হিসাব করে (এই হিসাব করাটাকেই আমরা প্রসেস করা বলছি মাঝে মধ্যে)। তো এই 0 এবং 1-গুলো রাখার জন্য আমাদের জায়গা দরকার। সেই জায়গাটি দেয় কম্পিউটারের মেমোরি। এই 0 আর 1, এগুলো হচ্ছে একেকটি বিট (ইংরেজিতে bit)। একটি বিট যেকোনো এক রকমের হবে, হয় শূন্য (0), না হয় এক (1)। তাহলে একটি বিট দিয়ে দুটি আলাদা জিনিস প্রকাশ করা সম্ভব, যখন বিটটি হবে 0 তখন এক রকম, আবার যখন 1 তখন আরেক রকম। তাহলে পাশাপাশি দুটি বিট দিয়ে কয়টি আলাদা জিনিস রাখা যায়? তোমরা একটু চিন্তা কর তো। চিন্তা করা শেষ হলে নিচের টেবিলটি দেখো:

তাহলে দুটি বিট পাশাপাশি রাখলে চারটি আলাদা জিনিস রাখা যায়: 00, 01, 10 ও 11। এবারে তোমার নিজে কিছু কাজ করতে হবে। খাতা-কলম নিয়ে বসে যাও এবং তিনটি ও চারটি বিটের ক্ষেত্রে কতগুলো আলাদা জিনিস রাখা সম্ভব সেটি বের কর। উত্তর হবে, যথাক্রমে 8 ও 16। তাহলে দাঁড়াচ্ছে 2, 3 ও 4টি করে বিটের ক্ষেত্রে যথাক্রমে 4, 8 ও 16টি পৃথক জিনিস রাখা যায়। তাহলে তোমাদের যেহেতু বুদ্ধিশুদ্ধি বেশি, তোমরা সহজেই বলে দিতে পারবে, 5টি বিটের জন্য 32, 6টি বিটের জন্য 64, 7টি বিটের জন্য 128টি পৃথক জিনিস রাখা সম্ভব। তাহলে 8টি বিটের জন্য কত? উত্তর হবে 256। আর যাদের সামান্য একটু গাণিতিক বুদ্ধি আছে, তারা কিন্তু এতক্ষণে মনে মনে একটি সূত্র বের করে ফেলেছ: nটি বিট থাকলে 2^n টি পৃথক জিনিস রাখা সম্ভব।

বাইট শব্দটি নিশ্চয়ই তোমরা শুনেছ? ইংরেজিতে লিখলে byte (তবে এই শব্দের মানে কিন্তু কামড় নয়, সেটির ইংরেজি bite)। আটটি বিট পাশাপাশি রেখে তৈরি হয় একটি বাইট। তাহলে এক বাইটে কতটি আলাদা জিনিস রাখা যায়? আমি জানি তোমরা চট্ করে বলে দিতে পারবে, 256টি।

তোমরা সবাই ক্যারেক্টার টাইপের (char) ভ্যারিয়েবলের সঙ্গে পরিচিত। তাহলে এখন তোমরা নিশ্চয়ই বুঝতে পারছ যে, একটি ক্যারেক্টার টাইপের ভ্যারিয়েবলে 256টি আলাদা জিনিস রাখা সম্ভব। এজন্যই আমরা বিভিন্ন অক্ষর, সংখ্যা, চিহ্ন এগুলোকে ক্যারেক্টার টাইপের ভ্যারিয়েবলের মধ্যে রাখি। প্রতিটি অক্ষরের একটি মান রয়েছে যাকে সংখ্যা দিয়ে প্রকাশ করা যায়। যেমন a-এর মান 97, b-এর মান 98, c-এর মান 99, এভাবে z-এর মান 122। আবার A-এর মান 65, B-এর মান 66, C-এর মান 67, এভাবে Z-এর মান 90, 0 থেকে 9 পর্যন্ত চিহ্নগুলোর মান যথাক্রমে 48 থেকে 57। এই মানগুলোকে বলে ASCII মান। ASCII হচ্ছে American Standard Code for Information Interchange-এর সংক্ষিপ্তরূপ। ইংরেজি সব অক্ষর, চিহ্ন সবগুলোরই আসকি (ASCII) মান রয়েছে। এখন তোমার মনে প্রশ্ন জাগতে পারে, পৃথিবীর বাকি ভাষাগুলো কী দোষ করল? তাদের সব অক্ষরের জন্য আসকি মান নেই কেন? আসলে 8 বিটে আমরা তো মোটে 256টি জিনিস রাখতে পারি, তাই সবার জায়গা দেওয়া সম্ভব হয় নি। অন্য সব ভাষার জন্য রয়েছে ইউনিকোড (Unicode)।

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

আমাদের প্রথম প্রোগ্রাম:


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

আমাদের দ্বিতীয় প্রোগ্রাম:


এখন তোমার কাজ হবে একটি ফাংশন লেখা, যেটি প্যারামিটার হিসেবে একটি ক্যারেক্টার টাইপের ভ্যারিয়েবল নেবে এবং সেটি যদি কোনো অঙ্ক (digit) হয়, তবে 1 রিটার্ন করবে, আর না হলে 0 রিটার্ন করবে। কাজ শেষ হলে চলো, আমরা মেমোরি নিয়ে আলাপ-আলোচনায় ফেরত যাই।

ইন্টিজার টাইপের ভ্যারিয়েবলের আকার হচ্ছে চার বাইট, মানে 32 বিট। এই 32 বিটে আমরা 2^32টি বা 4,294,967,296টি সংখ্যা রাখতে পারি। এখন আমরা যদি কেবল ধনাত্মক সংখ্যা রাখতে চাই, তাহলে 0 থেকে 4,294,967,295 পর্যন্ত রাখা যাবে। এ ধরনের ভ্যারিয়েবলকে বলে unsigned ভ্যারিয়েবল। আর যেসব ভ্যারিয়েবলে ধনাত্মক ও ঋণাত্মক – উভয় প্রকারের সংখ্যা রাখা যায়, তাকে বলে signed ভ্যারিয়েবল, তবে এক্ষেত্রে আলাদাভাবে সেটির উল্লেখ থাকে না। তাহলে আমরা বুঝতে পারলাম কেন int টাইপের ভ্যারিয়েবলে -2,147,483,648 থেকে 2,147,483,647 পর্যন্ত সংখ্যা রাখা যায় আর কেন unsigned int টাইপের ভ্যারিয়েবলে 0 থেকে 4,294,967,295 পর্যন্ত সংখ্যা রাখা যায়।


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

কম্পিউটারের মেমোরিতে ক্ষুদ্রতম একক হচ্ছে বাইট। পরপর অনেকগুলো বাইট মেমোরিতে সাজানো থাকে। প্রতিটি বাইটের আবার নির্দিষ্ট ঠিকানা বা অ্যাড্রেস (address) রয়েছে। তুমি যখন কোনো ক্যারেক্টার ভ্যারিয়েবল ডিক্লেয়ার করবে, সেটি মেমোরির একটি বাইট দখল করে ফেলবে। আবার তুমি যদি ইন্টিজার ভ্যারিয়েবল ডিক্লেয়ার কর, তাহলে সেটি মেমোরির পরপর চারটি বাইট দখল করবে। ব্যাপারটি বোঝানোর জন্য নিচের ছবিটির মতো চিন্তা করা যায়। তোমরা দেখতে পাচ্ছ ছবিতে দশটি ঘর রয়েছে। প্রতিটি ঘরের আকার হচ্ছে এক বাইট। আবার প্রতিটি ঘরের আলাদা ঠিকানা বা অ্যাড্রেস রয়েছে। ধরে নিই, প্রথম ঘরের অ্যাড্রেস হচ্ছে 100। তাহলে পরের ঘরের অ্যাড্রেস হবে 101, তার পরের ঘরের অ্যাড্রেস হবে 102, এরকম। ছবিতে অ্যাড্রেসগুলো মূল ঘরের নিচে আরেকটি ঘরে লেখা হয়েছে।
এখন তুমি কোনো ভ্যারিয়েবল ডিক্লেয়ার করলে সেটি মেমোরির কোন ঘরটি দখল করবে, তা কিন্তু তোমার হাতে নেই, সেটি নির্ধারণ করবে অপারেটিং সিস্টেম। আবার তুমি যখন কোনো অ্যারে ডিক্লেয়ার কর, অ্যারের উপাদানগুলো কিন্তু মেমোরিতে পরপর জায়গা দখল করে। এবারে নিচের প্রোগ্রামটি ঝটপট টাইপ করে রান কর।

আউটপুট কী? একেক জনের আউটপুট একেক রকম হবে, কারণ মেমোরির কোন জায়গায় কোন ভ্যারিয়েবল থাকবে, তার কোনো ঠিক নেই। এখন তোমরা লক্ষ কর, কোনো ভ্যারিয়েবল যদি n হয়, তবে তার অ্যাড্রেস হচ্ছে &n। এ কারণেই আমরা scanf ফাংশন ব্যবহার করে কোনো ভ্যারিয়েবল ইনপুট নেওয়ার জন্য ভ্যারিয়েবলের নামের আগে & চিহ্ন ব্যবহার করি। কিন্তু অ্যারের বেলাতে সেটি করতে হয় না, কারণ অ্যারের নামটিতেই অ্যারের শুরুর অ্যাড্রেসটি থাকে। অর্থাৎ কোনো অ্যারে যদি হয় int ara[10], সেখানে ara-এর মান প্রিন্ট করলেই অ্যারের অ্যাড্রেস পাওয়া যায়। আর কোনো ভ্যারিয়েবলের অ্যাড্রেস প্রিন্ট করার জন্য আমরা %p ব্যবহার করতে পারি।
এখন তুমি নিচের প্রোগ্রামটিও আগের মতো রান করবে।

প্রোগ্রামটির প্রথম লাইনে প্রিন্ট হবে অ্যারের উপাদানগুলো। দ্বিতীয় লাইনে প্রিন্ট হবে অ্যারের শুরুর অ্যাড্রেস, মানে মেমোরির যেই জায়গা থেকে অ্যারেটি শুরু হয়েছে, সেই জায়গার ঠিকানা (একেক জনের কম্পিউটারে আউটপুট একেক রকম হবে)। দ্বিতীয় লাইনে যা প্রিন্ট হবে, তৃতীয় লাইনে ঠিক তা-ই প্রিন্ট হবে, কারণ অ্যারের শুরুর অ্যাড্রেস আর অ্যারের প্রথম উপাদানের অ্যাড্রেস একই জিনিস। চতুর্থ লাইনে অ্যারের দ্বিতীয় উপাদানের অ্যাড্রেস প্রিন্ট হবে, যা প্রথম উপাদানের অ্যাড্রেসের চেয়ে চার বেশি। কারণ প্রথম উপাদান পরপর চারটি বাইট দখল করবে। যদিও তোমার মনে হতে পারে, 50 কেন চার বাইট জায়গা নেবে, এক বাইটেই তো লিখা যায়, কিন্তু যখনই তুমি ডেটা টাইপ int বলে দিবে, তখনই চার বাইট জায়গা দখল হয়ে যাবে। যদিও বিভিন্ন ডেটা টাইপের ভ্যারিয়েবলের সাইজ, কম্পিউটারের আর্কিটেকচারভেদে ভিন্ন রকম হতে পারে, কিন্তু আমি ধরে নিচ্ছি, তোমার কম্পিউটারে ইন্টিজারের সাইজ চার বাইট। আর সেটি সত্য না হলে পরের প্রোগ্রামটি চালিয়ে তুমি সত্যটি জেনে নিতে পারবে। সি-তে sizoeof নামে একটি অপারেটর আছে, যেটি বলে দেয় কোন ভ্যারিয়েবলের সাইজ কত বাইট। নিচের প্রোগ্রামটি হুবহু টাইপ কর, তারপরে কম্পাইল ও রান কর। এখন নিজে নিজে চিন্তা করে বুঝে নাও যে sizeof কীভাবে ব্যবহার করতে হয়।


বিভিন্ন প্রকারের মেমোরি

এখন চলো জেনে নিই, কম্পিউটারে কত ধরনের মেমোরি আছে। কম্পিউটারের মেমোরিকে মোটা দাগে দুই ভাগে ভাগ করা যায়, অস্থায়ী ও স্থায়ী। ইংরেজিতে বলে ভোলাটাইল (volatile) ও নন-ভোলাটাইল (non volatile)। যেসব মেমোরিতে কম্পিউটার বন্ধ করার পরেও ডেটা সংরক্ষিত থাকে, তাকে বলে স্থায়ী (non volatile) মেমোরি, যেমন হার্ডডিস্ক, রম, ডিভিডি, ইউএসবি ড্রাইভ। আর যেসব মেমোরির ডেটা কম্পিউটার বন্ধ (ক্ষেত্রবিশেষে প্রোগ্রাম বন্ধ) করলে হারিয়ে যায়, সেগুলোকে বলে অস্থায়ী মেমোরি, যেমন র‍্যাম (RAM)। কম্পিউটার প্রোগ্রামগুলো ডেটা নিয়ে কাজ করার সময় অস্থায়ী মেমোরি ব্যবহার করে। স্থায়ী মেমোরিগুলো বেশ ধীরগতির হয় বলে সেগুলো ব্যবহার করা হয় না।
কম্পিউটারের প্রসেসরের মধ্যেও কিন্তু মেমোরি আছে, প্রসেসরের সবচেয়ে কাছে থাকে রেজিস্টার, আর তার পরেই থাকে ক্যাশ মেমোরি। সি ল্যাঙ্গুয়েজে আমরা চাইলে কোনো ভ্যারিয়েবলকে রেজিস্টারে রাখার জন্য এভাবে ডিক্লেয়ার করতে পারি: register int number;। সেসব ভ্যারিয়েবলকেই আমরা রেজিস্টারে রাখার চেষ্টা করব যেগুলো প্রোগ্রামের ভেতরে সবচেয়ে বেশি ব্যবহার করা হয়। তবে আজকাল রেজিস্টারে এভাবে না রাখলেও চলে, কম্পাইলারগুলো নিজেরাই বুঝে নেয় কোন ভ্যারিয়েবল কোথায় রাখতে হবে। রেজিস্টারের চেয়ে ক্যাশ মেমোরির আকার বড়, মানে বেশি তথ্য ধারণ করতে পারে, তবে গতি একটু কম। তারপরে আসে র‍্যাম। র‍্যাম প্রসেসরের বাইরে মাদারবোর্ডে সংযুক্ত থাকে। ক্যাশের তুলনায় র‍্যামের আকার বেশ বড়, তবে গতিও কম। এখন তোমরা প্রশ্ন করতে পারো, রেজিস্টার আর ক্যাশের আকার আরও বেশি হলে কী সমস্যা ছিল? শুধু শুধু র‍্যামের ব্যবহার কেন করছি? আসলে রেজিস্টার মেমোরি তৈরিতে খরচ সবচেয়ে বেশি, তারপরে ক্যাশ মেমোরি। র‍্যাম তাদের তুলনায় বেশ সস্তা। র‍্যামের পরে আসে ভার্চুয়াল মেমোরি। র‍্যামে যখন জায়গা হয় না, তখন হার্ডডিস্কের একটা অংশকে কম্পিউটারের অপারেটিং সিস্টেম মেমোরি হিসেবে ব্যবহার করতে দেয় প্রোগ্রামগুলোকে। সেটি অবশ্যই র‍্যামের তুলনায় অনেক ধীর গতির। ছবি-২ এর দিকে একবার চোখ বুলিয়ে নাও। এখানে বিষয়গুলো একটু সহজবোধ্য করে লেখা হয়েছে, তোমরা এগুলো আরও ভালোভাবে শিখতে পারবে যখন তোমরা কম্পিউটার আর্কিটেকচারের ওপর লেখাপড়া করবে। আপাতত মেমোরি নিয়ে এটুকু ধারণা থাকলেই চলবে। আর আমরা এখন প্রোগ্রামিং করার সময় মেমোরি বলতে র‍্যামকেই বুঝব, বইয়ের বাকি অংশেও সেভাবে লেখা হবে। পরবর্তী অধ্যায়ে আমরা পয়েন্টার নিয়ে আলোচনা করব।

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

এলিয়েন গুপী

সমস্যাটি পড়তে এবং সমাধান জমা দিতে ভিজিট করুন দ্বিমিক অনলাইন জাজ।
লিঙ্কঃ https://dimikoj.com/problems/26/

৫২টি প্রোগ্রামিং সমস্যা ও সমাধান বইতে এই সমস্যার সমাধান নিয়ে আলোচনা করা হয়েছে।

লঘিষ্ঠ সাধারণ গুণিতক

সমস্যাটি পড়তে এবং সমাধান জমা দিতে ভিজিট করুন দ্বিমিক অনলাইন জাজ।
লিঙ্কঃ https://dimikoj.com/problems/25/

৫২টি প্রোগ্রামিং সমস্যা ও সমাধান বইতে এই সমস্যার সমাধান নিয়ে আলোচনা করা হয়েছে।

একান্তর উপাদান

সমস্যাটি পড়তে এবং সমাধান জমা দিতে ভিজিট করুন দ্বিমিক অনলাইন জাজ।
লিঙ্কঃ https://dimikoj.com/problems/24/

৫২টি প্রোগ্রামিং সমস্যা ও সমাধান বইতে এই সমস্যার সমাধান নিয়ে আলোচনা করা হয়েছে।