লেখক পরিচিতি
লেখকের নাম:
আহমেদ ওয়াহিদ মাসুদ
মোট লেখা:৯৮
লেখা সম্পর্কিত
পাবলিশ:
২০১২ - সেপ্টেম্বর
সহজ ভাষায় প্রোগ্রামিং সি/সি++
সি দিয়ে হয়তো এখনকার সব আধুনিক সফটওয়্যার বানানো সম্ভব নয়, তবে সব ধরনের ল্যাঙ্গুয়েজের ভিত্তি হলো সি। আসলে সি দিয়ে আধুনিক সফটওয়্যারের লজিক দাঁড় করানো সম্ভব এবং এটিই একটি সফটওয়্যারের প্রধান অংশ।
সি-তে ফাংশন ব্যবহারের সুবিধা একদিকে যেমন প্রোগ্রামকে করে দ্রুততর, তেমনি ইউজারের জন্য কোডিং করে তুলে আরও সহজ। ফাংশনের ব্যবহার নিয়ে আগের সংখ্যায় আলোচনা করা হয়েছে। এ সংখ্যায় ফাংশনের ব্যবহারের আরও গভীরে ঢোকা হয়েছে এবং দেখানো হয়েছে কীভাবে ফাংশন আসলে কাজ করে এবং তা কী কী উপায়ে ব্যবহার করা যায়।
ফাংশন প্রোটোটাইপ
শুরুতেই ফাংশনের প্রোটোটাইপ সম্পর্কে আলোচনা করা হয়েছে। আমরা জানি, সি-তে প্রোগ্রাম শুরু হয় মেইন ফাংশন থেকে। প্রোগ্রামে অনেক বিল্টইন ফাংশন ব্যবহার করা হয় এবং এসব বিল্টইন ফাংশন সংশ্লিষ্ট হেডার ফাইল থেকে ইম্পোর্ট করা হয়। তাই আলাদা কোনো কিছু করার প্রয়োজন পড়ে না। কিন্তু ইউজার যদি নিজের নতুন ফাংশন ব্যবহার করতে চান, তাহলে প্রত্যেক ফাংশনের প্রোটোটাইপ ব্যবহার করতে হবে। ফাংশনের প্রোটোটাইপ হলো আর কিছুই নয় শুধু ফাংশনের নাম মেইন ফাংশনের আগে লিখে দেয়া। এটি লেখার নিয়ম হলো : ‘রিটার্ন টাইপ ফাংশনের নাম (ফাংশনের প্যারামিটার)’। এটি মেইন ফাংশনের আগে যেকোনো জায়গায় লিখলেই হবে, শেষে সেমিকোলন দিতে হবে। তবে এখানে একটি বিশেষ নিয়ম আছে। ইউজার ডিফাইন্ড ফাংশনের বডি যদি মেইন ফাংশনের পরে লেখা হয়, তাহলে উল্লিখিত ফাংশনের প্রোটোটাইপ দেয়া আবশ্যক, আর বডি যদি মেইন ফাংশনের আগেই লেখা হয় তাহলে আর প্রোটোটাইপ দিতে হবে না। অবশ্যই খেয়াল রাখতে হবে প্রোটোটাইপে দেয়া ফাংশনের রিটার্ন টাইপ, ফাংশনের নাম এবং প্যারামিটার যেন ফাংশনের বডিতে দেয়া রিটার্ন টাইপ, নাম এবং প্যারামিটার একই হয়। ফাংশনের প্যারামিটারে ব্যবহার হওয়া ভেরিয়েবলের রিটার্ন টাইপ অবশ্যই দিতে হবে। যেমন : ইউজার যদি নিউ ফাংশন নামে একটি ফাংশন তৈরি করেন এবং তার প্যারামিটারে যদি দুটি ইন্টিজার থাকে তাহলে এর প্রোটোটাইপ হবে : void newFunction(int x,int y);। ফাংশনের বডির শুরুতেও এরকম ডেফিনেশন দিতে হবে, শুধু পার্থক্য হলো কোনো সেমিকোলন থাকবে না। এবার ফাংশনের রিটার্ন টাইপ এবং ফাংশন দিয়ে কীভাবে ভ্যালু রিটার্ন করা সম্ভব তা নিয়ে আলোচনা করা যাক।
রিটার্ন টাইপ মানে যেকোনো ধরনের ডাটা টাইপ অথবা যদি কিছুই রিটার্ন করার দরকার না হয় সেক্ষেত্রে ভয়েড। ওপরের উদাহরণ থেকে দেখা যাচ্ছে ফাংশনটির রিটার্ন টাইপ ভয়েড অর্থাৎ এই ফাংশনটিকে যেখানে কল করা হবে সেখানে এটি কোনো ভ্যালু রিটার্ন করবে না। ফাংশন কী রিটার্ন করবে না করবে সেটি return; স্টেটমেন্ট দিয়ে নির্ধারণ করা হয়। যদি ফাংশনকে কোনো ভ্যালু রিটার্ন করতে হয় তাহলে রিটার্ন স্টেটমেন্টের পর সেই ভ্যালু দিয়ে হয়। আর যদি কোনো ভ্যালু রিটার্নের দরকার না হয়, তাহলে শুধু রিটার্ন লিখে সেমিকোলন দিতে হবে। অথবা কোনো রিটার্ন স্টেটমেন্ট না লিখলেও হবে, সেক্ষেত্রে ফাংশন যেখানে শেষ হয়ে যাবে, সেখান থেকে সে নিজেই রিটার্ন করবে। নিচে রিটার্ন নিয়ে একটি উদাহরণ দেয়া হলো। ধরা যাক, এমন একটি ফাংশন লেখার প্রয়োজন পড়ল যেন তা একটি ইন্টিজার, একটি ক্যারেক্টার নিতে পারে এবং সেই ক্যারেক্টারের আস্কিং ভ্যালু দিয়ে (স্ট্যান্ডার্ড ভ্যালু) ওই ইন্টিজারকে গুণ করলে যে ভ্যালু পাওয়া যায়, তা রিটার্ন করে। তাহলে ফাংশনের বডি নিচের মতো হবে :
int newFunction(int x,char y)
{
printf(`the value is returned!!’);
return x*y;
}
এখানে দেখা যাচ্ছে, ফাংশনটি ইন্টিজার টাইপের ডাটা রিটার্ন করতে সক্ষম। এর দুটি প্যারামিটার অর্থাৎ এটি দুটি ভেরিয়েবল নিতে পারবে, যার একটি ইন্টিজার এবং আরেকটি ক্যারেক্টার। ভ্যালু নেয়ার পর এটি প্রদত্ত লাইনটি প্রিন্ট করবে, তারপর নির্দিষ্ট ভ্যালু রিটার্ন করবে। ভ্যালু রিটার্ন করার অর্থ হলো যদি প্রোগ্রামে কোথাও লেখা থাকে যে i=newFunction(2,A) তাহলে i এর ভ্যালু হিসেবে ১৩০ নির্ধারিত হবে, কারণ A-এর আস্কিং ভ্যালু ৬৫।
রিকার্সন
সব প্রোগ্রামিংয়ের জন্য একটি সত্যি কথা হলো : কোনো কোড ইউজারের জন্য বোঝা যত কঠিন হবে তা কমপিউটারের জন্য রান করা তত সহজ হবে, অর্থাৎ কম রিসোর্স নেবে অথবা কম টাইম নেবে। আর কোনো কোড ইউজারের জন্য বোঝা যত সহজ হবে তা কমপিউটারের জন্য রান করা তত কঠিন হবে অর্থাৎ সেই কোড বেশি রিসোর্স টানবে অথবা প্রোগ্রামের রান টাইম বেশি হবে। রিকার্সন থেকে বলা যায় অ্যাডভান্সড সি প্রোগ্রামিং শুরু। রিকার্সনের মাধ্যমে প্রোগ্রামের রানটাইম অনেক কমানো সম্ভব, প্রোগ্রাম আরও এফিসিয়েন্ট করা সম্ভব এবং এতে প্রোগ্রামের জটিলতা অনেকাংশে কমে যায়। তবে রিকার্সনের কোড কিছুটা কঠিন, এটি পুরোটাই কনসেপচুয়াল বিষয়, তাই বুঝতে একটু কষ্ট হতে পারে, তবে রিকার্সনের মাধ্যমে কোড করলে অনেক বড় প্রোগ্রামকে যেমন আকারে অনেক ছোট করা সম্ভব, তেমনি প্রোগ্রামের মানও এতে অনেক বেড়ে যায়।
রিকার্সনের বেসিক ধারণা খুব সহজ। একটি ফাংশন যখন নিজেই নিজেকে কল করে, তখন তাকে রিকার্সন বলে। তবে রিকার্সন শুধু একটি ফাংশনের মধ্যেই সীমাবদ্ধ থাকে না। একটি ফাংশনকে যদি অন্য ফাংশনের মধ্যেও বারবার কল করা হয়, তাহলেও সেটি রিকার্সন হয়। খেয়াল রাখতে হবে, ফাংশনের এই বারবার কল যেন কোনো লুপ দিয়ে করা না হয়। লুপ ব্যবহার করলে সেটি আর রিকার্সন হবে না। রিকার্সনের বেসিক উদ্দেশ্যই হলো লুপের মতো কাজ করা, কিন্তু লুপ ব্যবহার করা যাবে না। আসলে এটি লুপের বিকল্প হিসেবে কাজ করে। নিচে একটি ফাংশনের বডি দেয়া হলো। এটি মূলত কোনো নাম্বারের ফ্যাক্টরিয়াল বের করার ফাংশন। আমরা জানি কোনো নাম্বার n-এর ফ্যাক্টরিয়ালের সূত্র হলো n(n-1)(n-2)….
int fac(int n)
{
if(n<=1)
return 1;
else
return n*fac(n-1);
}
এখানে লক্ষণীয়, ফাংশনটি নিজেই নিজেকে কল করছে। প্রথমে n-এর ভ্যালু যদি ১ বা তার কম হয়, তাহলে এটি ১ রিটার্ন করবে। এখন আমরা জানি, ১-এর ফ্যাক্টরিয়াল ১। আবার n-এর ভ্যালু যদি ৩ হয় তাহলে এটি else-এ ঢুকবে। এখানে আবার এই ফাংশনটিকে কল করা হবে এবং তার প্যারামিটার হিসেবে ২ পাঠানো হবে। অর্থাৎ এই ফাংশনে n-এর ভ্যালু ২ হলে যে ফলাফল আসবে তার সাথে n গুণ করে এটি রিটার্ন করবে। আবার নতুন করে যে কল করা হলো সেখানে n=2 হওয়ার কারণে প্রোগ্রাম আবার else-এ যাবে এবং আবার রিকার্সন হবে। সেখানে ফাংশনটিকে আবার কল করা হবে এবং সেখানে প্যারামিটার দেয়া হবে ১। এখানে ফাংশন ১ সহকারে রিটার্ন করবে, কারণ n<=1 হলে ১ রিটার্ন করার কমান্ড দেয়া আছে। সেই ১-এর সাথে দ্বিতীয়বারের n অর্থাৎ ২ গুণ হবে। এভাবে ২ রিটার্ন হবে প্রথমবার যখন এই ফাংশনটিকে কল করা হয়েছে সেখানে। সেখানে রিটার্ন করা ভ্যালু হলো ২, এর সাথে বর্তমান n=3 গুণ হবে। এভাবে ৬ রিটার্ন হবে মূল প্রোগ্রামে।
রিকার্সন সি প্রোগ্রামিং ল্যাঙ্গুয়েজের একটি অন্যতম বৈশিষ্ট্য। এটি সি ল্যাঙ্গুয়েজকে করেছে অনেক সহজ এবং দ্রুততর। ঠিকমতো রিকার্সন ব্যবহার করতে পারলে প্রোগ্রাম অনেক উন্নত করা সম্ভব।
কজ ওয়েব
ফিডব্যাক : wahid_cseaust@yahoo.com