পাতা

উদোর পিণ্ডি বুধোর ঘাড়ে


তোমার ক্লাস শুরুর বেশ কিছুদিন হয়ে গেছে। এর মধ্যে একদিন ধুপ করে তোমার স্যার তোমাকে একটা অ্যাসাইনমেন্ট দিয়ে বসল। তোমাকে চায়নিজ ভাষার সবগুলো অক্ষর লিখে নিয়ে আসতে পারবে। তুমি মনে মনে ভাবলে এ আর এমন কী! কিন্তু, বাসায় গিয়ে গুগল করতেই তোমার চক্ষু চড়ক গাছ! একেক গবেষকের তথ্য অনুযায়ী চায়নিজ ভাষার অক্ষরের সংখ্যা একেক। সবচেয়ে ছোট লিস্টিতেই আছে প্রায় ২,৬০০ অক্ষর। তুমি একবার মাথা চুলকে চিন্তা করলে, বাংলা ভাষার ৫০টা বর্ণই তোমার ঠিকমত মনে আছে কি’না। কিন্তু, অ্যাসাইমেন্ট তো করতেই হবে। কী করা যায়?
এখানে তুমি দু’টো কাজ করতে পারো। যদি তুমি খুব ব্রিলিয়ান্ট স্টুডেন্ট হও, তাহলে বসে বসে সেই ২,৬০০ অক্ষর পড়তে বসে যাবে (এর মধ্যে তুমি আরও জানতে পারবে, কোন কোন গবেষকের মতে চায়নিজ ভাষার অক্ষরের সংখ্যা লক্ষাধিক) । আর যদি তুমি ফাঁকিবাজ কেউ হও, তাহলে তোমার কোন চায়নিজ বন্ধুকে ধরিয়ে দেবে কাজটা করার জন্য। তুমি জেনে খুশি হবে, পৃথিবীর প্রায় সব প্রোগ্রামারও তোমার মতই ফাঁকিবাজ। তাই তারা একজনের কাজ আরেকজনের ঘাঁড়ে চাপানোর বেশ ভাল একটা পদ্ধতি বের করে রেখেছে। জিনিসটাকে বলে ফাংশন 
মনে কর, তুমি তোমার কোন চায়নিজ বন্ধুকে বলে রাখলে, তাকে তোমার হয়ে চায়নিজ ভাষার অক্ষরগুলো লিখে দিতে হবে। যখন তুমি তাকে কল করবে, তখন সে যেন অ্যাসাইমেন্টটা লিখে ফেলে। এমন বুঝ দিয়ে রাখার পর, যখনই তুমি তোমার বন্ধুকে কল করবে, তখনই সে তোমার কাজ করে দেবে।

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

ব্যাস, আমাদের এই ফাংশনটাকে কাজ বুঝিয়ে দেয়া শেষ। এখন আমরা আমাদের প্রোগ্রামের ভেতর থেকে যেখানেই এই ফাংশনটাকে কল করব, সেখানেই সে স্ক্রিনে a থেক z পর্যন্ত দেখিয়ে দেবে। আসলেই সে সেটা করে কি’না, সেটা আমরা একটু পরে দেখছি। তার আগে ফাংশনটাকে আমরা কিভাবে বোঝালাম তার কাজ, সেটা একটু নিজেরা বুঝে নেই। প্রথম শব্দ void এর ব্যাপারটা একটু পরে ব্যাখ্যা করছি। পরের শব্দ func টা হচ্ছে আমাদের ফাংশনের নাম। তুমি তোমার বন্ধুকে কল করার জন্য তার নাম্বারটা মোবাইলে একটা নাম দিয়েই সেইভ করে রাখো। ব্যাপারটা অনেকটা তেমনই। কম্পাইলার আমাদের ফাংশনটাকে একটা নাম্বার দিয়েই মনে রাখে। কিন্তু, আমরা নিজেরা তাকে মনে রাখার জন্যে একটা নাম দিয়ে দিই। এই নাম যা খুশি হতে পারে। func এর জায়গায় f বা function কিংবা vugichugi হলেও কোন সমস্যা ছিল না। তার পরে, () দিয়ে আমরা কম্পাইলারকে বুঝিয়ে দিই এটা একটা ফাংশন। আর তার পরে থাকা {} এই বন্ধনীর মধ্যে আমরা লিখে দিই ফাংশনটাকে আসলে কী করতে হবে। আমাদের func ফাংশনের ক্ষেত্রে এই কাজটা হচ্ছে, স্ক্রিনে a থেকে z পর্যন্ত প্রিন্ট করা। এবার আমাদের মূল প্রোগ্রামের ভেতরে ফাংশনটাকে নাম ধরে ডাক দিলেই সে তার কাজ করে দেবে। পুরো প্রোগ্রামটা নিচের মত –

একটা জিনিস আশা করি এরই মধ্যে তুমি খেয়াল করেছ। আমরা একটা ফাংশন যেভাবে লিখি int main() {} এই অংশটাও ঠিক একই ভাবে লেখা। হ্যাঁ, ঠিক ধরেছ। আসলে main() নিজেও একটা ফাংশন ছাড়া কিছুই না। ব্যাপারটা এভাবে কল্পনা করা যায় – কম্পিউটার হচ্ছে তোমার স্যার। তুমি হচ্ছ main() ফাংশন। তোমার স্যার পুরো ক্লাসের মধ্যে তোমাকে খুঁজে বের করে একটা কাজ করতে দেবে। সেই কাজটা তুমি নিজে করবে (অর্থাৎ main() ফাংশনের ভেতরেই করা হবে) না’কি তুমি অন্য কাউকে দিয়ে করিয়ে নেবে (অর্থাৎ অন্য কোন ফাংশনকে কল করবে) সেটা তার দেখার বিষয় না। কাজটা ঠিকঠাক মত হলেই হল।
এখন তোমার মাথায় আরেকটা নতুন চিন্তা আসা উচিৎ। আমরা যদি সরাসরি মেইনের ভেতরেই লিখে দিই কী করতে হবে, তাহলে সমস্যা কী? শুধু শুধু নতুন একটা ফাংশন তৈরি করে, তার মধ্যে যা যা দরকার লিখে সেটাকে আবার মেইন থেকে কল করার আদৌ কি কোন দরকার আছে? দরকার আছে কি নেই, সেটা বোঝার জন্য আমরা ওপরের প্রোগ্রামটাকে একটু বদলে নিচের মত করে লিখি।

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

এই প্রোগ্রামটা রান করলে দেখবে স্ক্রিনে 675 আর 7678 এর যোগফল দেখা যাচ্ছে।
ওপরের প্রোগ্রামটায় যখন () বন্ধনীর মধ্যে int a, int b লেখা হয়, তার সাথে সাথে a আর b নামের দু’টো ইন্টিজার ভ্যারিয়েবল তৈরি হয়। এর সাথে এটাও বুঝিয়ে দেয়া হয় যে, এই দু’টো ভ্যারিয়েবলের মান যখন এই ফাংশনকে কল করা হবে, তখন দিয়ে দেয়া হবে। আর ফাংশনের ভেতরে যা লেখা হয়েছে, সেটুকু বুঝতে তো তোমার কোন সমস্যা হওয়ার কথা না। শুধু স্ক্রিনে প্রিন্ট করা হয়েছে a আর b ভ্যারিয়েবল দু’টোর মান আর তাদের যোগফল।
তারপর আমরা যখন main () ফাংশনের ভেতরে add () ফাংশনটাকে কল করছি, তখন বন্ধনীর মধ্যেই a আর b ভ্যারিয়েবল দু’টোর মান দিয়ে দিচ্ছি। add () ফাংশনের বন্ধনীর ভেতরে মানগুলো যেই ক্রমে দেয়া হবে, ভ্যারিয়েবলের মানও সেই অনুসারে ঠিক করা হবে। আমরা যদি main () ফাংশনের ভেতরে add (675,7678) না লিখে add (7678, 675) লিখতাম তাহলে a ভ্যারিয়েবলের মান হত 7678 আর b ভ্যারিয়েবলের মান হত 675।
ঠিক এই জায়গাটায় এসে তোমার মনে আরেকটা প্রশ্ন জাগা উচিৎ। এতক্ষণে তুমি জানো main() কিংবা add() এর মত printf() ও একটা ফাংশন। কিন্তু, main() কিংবা add() ফাংশন কী করবে, সেটা আমরা প্রোগ্রামের মধ্যে লিখে দিলেও printf() ফাংশন কী করবে, সেটা কোথাও লিখিনি। কেবল, দরকার মত তাকে কল করেছি। তাহলে কাজটা করা হচ্ছে কিভাবে? এর উত্তরটা হচ্ছে, আসলে printf() ফাংশনকে কী করতে হবে, সেটা তোমার প্রোগ্রামেই লেখা আছে, যদিও তুমি নিজে সেটা লেখোনি। আমাদের প্রোগ্রামের প্রথম লাইনটাই ছিল #include <stdio.h> । এই লাইনটা যা করে হচ্ছে, stdio.h নামের একটা ফাইলকে তোমার প্রোগ্রামের সাথে জুড়ে দেয় (কিংবা ইনক্লুড করে)। printf() সহ আর বেশ কিছু ফাংশন কিভাবে কাজ করবে, সেটা stdio.h ফাইলে লেখা আছে।
এবার তাহলে ঝটপট একটা প্রোগ্রাম লিখে ফেলো তো, যেটা দু’টো double সংখ্যার বিয়োগফল স্ক্রিনে প্রিন্ট করবে।
পরদিন আবার ক্লাসে গেলে। স্যারকে তোমার অ্যাসাইনমেন্ট দেখালে। স্যার আরও খুশি। এবং আরও খুশি হয়ে তোমাকে আরও ঝামেলায় ফেলল। এবার তোমাকে স্যার বলল, সে তোমাকে দু’টো সংখ্যা দেবে। তোমাকে প্রথমে ‘তাদের যোগফল’ বের করতে হবে। তারপর ‘তাদের বিয়োগফল’ বের করতে হবে। তারপর ‘যোগফল আর বিয়োগফলকে গুণ’ করতে হবে। তুমি প্রথমে ভাবলে, এটাও তোমার বন্ধুকে দিয়ে করিয়ে নেবে। কিন্তু, তারপর আবার চিন্তা করলে, একজন এত খাটানো কি ঠিক হবে? তার বদলে এক কাজ করা যাক। প্রথমে একজনকে বলো, দু’টো সংখ্যা যোগ করে তার যোগফল তোমাকে ‘ফেরত দিতে’। তারপর, আরেকজনকে বলো, দু’টো সংখ্যা বিয়োগ করে তার বিয়োগফল তোমাকে ‘ফেরত দিতে’। অন্য আরেকজনকে বললে, দু’টো সংখ্যা গুণ করে, তার গুণফল স্ক্রিনে প্রিন্ট করতে। অর্থাৎ, আমাদের যে প্রথম দু’টো ফাংশন তাদের আমাদের বলে দিতে হবে যে, তাদেরকে কল করার সময় যে দু’টো সংখ্যা দেয়া হবে, সেগুলো যোগ বা বিয়োগ করার পর ফলাফলটা যেন তারা মেইন ফাংশনকে রিটার্ন করে। এই জিনিসটা কিভাবে করা যায়, দেখে নিই তাহলে।

আমাদের আগের যোগ করার ফাংশনটার সাথে এখনকার যোগ করার ফাংশনের মূল পার্থক্যটা হচ্ছে, আগে আমাদের শুরুর শব্দটা ছিল void আর এখন সেটা হয়ে গেছে int এবং আগে আমরা যোগফলটা স্ক্রিনে প্রিন্ট করে দিতাম আর এখন সেটা return নামে একটা শব্দের পরে লিখি। এই কাজ দু’টো করায় আসলে কী করা হচ্ছে? আমাদের আগে add ফাংশনের নামের আগে আমরা যখন void লিখতাম, সেটা দিয়ে বোঝাতো এই ফাংশনটা তার কাজ শেষ করার পরে মেইন ফাংশনকে কিছু ফেরত (return) করবে না। আর এখনকার ফাংশনের শুরুতে int লিখে আমরা বোঝাচ্ছি এটা মেইন ফাংশনকে একটা ইন্টিজার ফেরত দেবে। আর সেই ফেরত দেয়ার কাজটাই আমরা করেছি ফাংশনের শেষ লাইনে return c লিখে। অর্থাৎ c ভ্যারিয়েবল এর যে মান, সেটাই ফাংশনটা মেইন ফাংশনকে ফেরত দেবে। সেটা দিয়ে মেইন ফাংশন কী করবে সেটা তার ব্যাপার। তাহলে আমরা পুরো প্রোগ্রামটা দেখে ফেলি।


এখানে, মেইন ফাংশনের মধ্যে যা হচ্ছে তা হল, আমরা প্রথমে a, b নামের দু’টো ভ্যারিয়েবল তৈরি করা হয়েছে। তারপর summation নামে আরেকটা ভ্যারিয়েবল তৈরি করে তার মান দেয়া হয়েছে add ফাংশনটা যে মান রিটার্ন করে, তাই। তারপরে, subtraction নামে আরেকটা ভ্যারিয়েবল তৈরি করে, তার মান দেয়া হয়েছে subtract ফাংশন যে মান রিটার্ন করে, তাই। সবশেষে multiply ফাংশনকে কল করে, তাকে মান addition আর subtraction এর মান দিয়ে দেয়ায়, সে তাকে দেয়া নির্দেশ অনুযায়ী মান দু’টো স্ক্রিনে প্রিন্ট করে দিয়েছে।
রিটার্ন জিনিসটা বুঝে ফেলার সাথে সাথে তোমার মাথায় আরেকটা প্রশ্নের উদয় হওয়া উচিৎ। আমরা তো main() ফাংশনের আগে int লিখে দিই যেটা দিয়ে বোঝায় মেইন ফাংশন একটা ইন্টিজার রিটার্ন করবে। কিন্তু, ফাংশনের শেষ লাইনে তো আমরা কোন কিছু রিটার্ন করি না। তাহলে কম্পাইলার কোন এরর দেখায় না কেন? আসলে, মেইন যেহেতু একটা স্পেশাল ফাংশন তাই, এটার শেষে রিটার্ন না লিখলেও কম্পাইলার নিজে থেকে return 0 নামে একটা লাইন যোগ করে নেয়। এটা কেবলমাত্র মেইন ফাংশনের জন্যই সত্যি। অন্য যেকোন ফাংশনের জন্য আমাদের রিটার্ন টাইপ void না হলে অবশ্যই কোন মান রিটার্ন করতে হবে। নইলে কম্পাইলার এরর দেখাবে।
এসব কাজ ঠিকঠাক করে তুমি তোমার স্যারকে দেখালে। স্যার তো আরও খুশি। এবার তোমাকে বলল, স্যার তোমাকে যে দু’টো সংখ্যা দেবে প্রথমে তার গুনফল আর ভাগফল বের করতে হবে। তারপর সেই গুণফল আর ভাগফলের যোগফল স্ক্রিনে প্রিন্ট করতে হবে। তারপর সেই গুণফল আর ভাগফলের বিয়োগফল স্ক্রিনে প্রিন্ট করতে হবে। এই কাজের প্রোগ্রামটা নিজে নিজে লিখে ফেলো তো। ভাল কথা, কোন সংখ্যার যদি দশমিক অংশ থাকে, সেটা যে ইন্টিজারের মধ্যে রাখা যায় না, সেটা মনে আছে তো?


No comments:

Post a Comment