Skip to main content

আসুন বাংলায় Programing C শিখি...


প্রোগ্রামিং কেন :
বাংলায় সি প্রোগ্রামিং থেকে কিভাবে প্রোগ্রামিং করতে হয়, কিভাবে নিজে একটা প্রোগ্রাম লিখব পাশা পাশি একটা সফটওয়ার বা প্রোগ্রাম লিখতে কি কি লাগবে, এসব সম্পর্কে জানা যাবে। আমরা যত গুলো অটোমেটিক মেশিন দেখি, সব গুলোই এক বা একের অধিক প্রোগ্রাম দিয়ে চলে। আর প্রোগ্রামটা লেখা হয় প্রোগ্রামিং ল্যাঙ্গুয়েজ দিয়ে। প্রোগ্রামিং জানলে যে শুধু কম্পিউটারের জন্যই সফটওয়ার তৈরি করা যাবে এমন না, সব কিছুর জন্যই প্রোগ্রাম বানানো যাবে। ছোট্ট একটা ক্যালকুলেটর হতে শুরু করে রোবোট বা এয়ারক্রাফট পর্যন্ত সব কিছুর প্রোগ্রাম।
অনেক গুলো Programming Language রয়েছে শেখার জন্য। এ গুলোর মধ্যে জনপ্রিয় একটা হচ্ছে এই C Programming। ডেনিস রিচি (জন্ম সেপ্টেম্বর ৯, ১৯৪১ – মৃত্যু অক্টোবর ৮, ২০১১) এর ডেভেলপ করা এই সি ল্যাঙ্গুয়েজ থেকে নতুন অনেক গুলো ল্যাঙ্গুয়েজই তৈরি হয়েছে পরবর্তিতে। এ জন্য এই একটি ল্যাঙ্গুয়েজ ভালো করে শিখলে পরবর্তিতে অনেক গুলো ল্যাঙ্গুয়েজে সহজেই কোড লেখা যায়।
কম্পিউটারকে ইন্সট্রাকশন দেওয়ার প্রক্রিয়া হচ্ছে প্রোগ্রামিং। ইন্সট্রাকশন গুলো কিছু নির্দিষ্ট নিয়ম মেনে লিখতে হয়। যে নিয়ম গুলো মেনে প্রোগ্রাম লিখতে হয়, তা হচ্ছে প্রোগ্রামিং ল্যাঙ্গুয়েজ। সি শিখতে শিখতে আমাদের অনেক কিছুই শেখা হয়ে যাবে। একসময় আমরা সফটওয়ার, ওয়েব সাইট বা মোবাইল অ্যাপ, হোম অটোমেশন ইত্যাদির জন্য সফটওয়ার তৈরি করতে পারব। আর তা পারব আজ যদি আমরা শেখা শুরু করি। শেখা খুবি সহজ। যা যা লাগবে, তা হচ্ছে একটা কম্পিউটার, ইন্টারনেট আর কিছু না। বাকি গুলো ইন্টারনেট থেকেই শিখে নেওয়া যাবে। প্রোগ্রাম লেখার জন্য দরকার হচ্ছে একটা টেক্সট এডিটর বা আইডিই। 

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

প্রথম সি প্রোগ্রাম ঃ

প্রোগ্রামিং করার জন্য দরকার একটা কম্পিউটার আর একটা কম্পাইলার। দুইটার মধ্যেই কি সদৃশ্য তাই না? দুটাই ক দিয়ে শুরু এবং “ম্প” যুক্ত বর্ণ রয়েছে।
আপনার একটা কম্পিউটার রয়েছে তা না হলে তো এ লেখাটা পড়তে পারতেন না, তাই না? এবার দরকার একটা কম্পাইলার। একটা সি কম্পাইলার। যে আমাদের কোড প্রোগ্রামিং এর কোড গুলোকে কম্পাইল করে দিবে।
কম্পাইলার কেন দরকার তা বলছি আগে। আমাদের আমরা যা লিখি কম্পিউটার তা পড়তে পারে না । কম্পিউটারের জন্য দরকার মেশিন ল্যাঙ্গুয়েজ। আমাদের সি প্রোগ্রামিংকে মেশিন ল্যাঙ্গুয়েজে পরিবর্তন করে দেয় এই কম্পাইলার। আমরা সি কোড লেখা ও কম্পাইল করার জন্য CodeBlocks IDE ব্যবহার করব । CodeBlocks ডাউনলোড করতে চাইলে নিচের লিঙ্ক এ গিয়ে codeblocks-12.11mingw-setup_user.exe টি ডাউনলোড করে নিন।
তারপর ইন্সটল করুন। ওপেন করুন। তাহলে নিচের মত দেখতে পারেবন।

ইন্সটল হলে আপনি কোড লেখার জন্য প্রস্তুত।
এখান থেকে Create New Project এ ক্লি করুন।


এখান থেকে Console Application সিলেক্ট করে Go তে ক্লি করুন।



এবার C সিলেক্ট করে Next এ ক্লিক করুন। Project Title বক্স এ আপনার প্রজেক্ট এর নাম দিন। যেমন hello. Folder to create project in বক্স থেকে আপনার প্রজেক্টটি কোন ফোল্ডারে সেভ করতে চান তা সিলেক্ট করুন। Next এ ক্লি করুন। এবার Finish এ ক্লি করুন।
এবার ডান পাশে আপনার workspace দেখতে পাবেন। ঐখানে আপনার প্রোজেক্ট গুলো দেখাবে। hello এর + চিহ্নতে ক্লিক করুন। তারপর Source এর + চিহ্নতে ক্লিক করুন এবং main.c এর উপর ক্লিক করুন। CodeBlocks একটা সিম্পল একটা কোড টেম্পলেট তৈরি করে প্রতি প্রজেক্টের জন্য, তা দেখাবে। যার মধ্যে লেখা থাকবেঃ
#include<stdio.h>
int main()
{
    printf("Hello world");
    return 0;
}
আমাদের কোডটি কম্পাইল এবং রান করতে হবে তার জন্য ফাইল মেনু থেকে Build এ ক্লিক করুন এবং Build and Run এ ক্লিক করুন। তাহলে আপনার সি প্রোগ্রামটি কম্পাইল হবে এবং রান হবে। এবং নিচের মত আউটপুট দিবেঃ

আপনি যদি উপরের প্রোগ্রামটি রান করাতে পারেন, তাহলে আপনাকে অভিনন্দন এবং স্বাগতম প্রোগ্রামিং এর মজার দুনিয়াতে। না করতে পারলে মন খারাপ করার দরকার নেই। আবার একটু চেষ্টা করুন প্রথম থেকে। তাহলেই হবে।
উপরের কোডে আমরা কি লিখছি তা এবার একটু ব্যাখ্যা করা যাক।
আমাদের প্রোগ্রামের প্রথম লাইন হচ্ছে #include<stdio.h> । include মানে হচ্ছে কোন কিছু যুক্ত করা। stdio এর পূর্ণরূপ হচ্ছে standard input output. stdio.h এর .h দিয়ে বুঝানো হয় এটা একটা header ফাইল। আর পুরো লাইন দিয়ে বুঝানো হয় যে standard input output কে যুক্ত কর। standard input output সম্পর্কে আরেকটু পরে বলব।
এর পরের লাইন হচ্ছে int main(), এটিকে বলা হয় মেইন ফাংশন। আমরা যখন প্রোগ্রামটি রান করাবো তখন এ মেইন ফাংশন থেকে কাজ করা শুরু করবে। তাই সব প্রোগ্রামে একটি (এবং কেবল একটি) মেইন ফাংশন থাকতে হয়। মেইন ফাংশনের শুরুতে দ্বিতীয় বন্ধনী দিয়ে শুরু করতে হয়। মেইন ফাংশন শেষও করতে হয় একটি দ্বিতীয় বন্ধনী দিয়ে।
মেইন ফাংশন এর দ্বিতীয় বন্ধনী এর ভেতর প্রথম লাইন লিখছি আমরা printf(“Hello world!”);
এখানে printf() হচ্ছে একটি ফাংশন। printf এর মানে হচ্ছে print formatted। এটি একটি লাইব্রেরী ফাংশন যাকে স্ট্যান্ডার্ড আউপুট ফাংশন বলে। printf() এর কাজ হচ্ছে কনসোলে/স্ক্রিনে কিছু প্রিন্ট করা। ডবল কোটেশন চিহ্নের ভেতরে আমরা যা লিখব তা-ই স্ক্রিনে সে প্রিন্ট করবে। আমরা প্রথমেই যে একটি লাইন লিখছি #include<stdio.h> । printf() ফাংশনটি কিভাবে কোন কিছু প্রিন্ট করে তা লেখা রয়েছে এই stdio.h ফাইলে।
এর পর আমরা আরেকটি লাইন লিখছি return 0; আমরা বলছি যে main হচ্ছে একটা ফাংশন। প্রত্যক ফাংশন এর একটা return মান থাকতে হয়। যা ফাংশন এর কাজ শেষে কিছু একটা রিটার্ন করে। return 0 মানে শূন্য রিটার্ন করা। এ সম্পর্কে পরে আরো বিস্তারিত জানা যাবে যখন আমরা ফাংশন নিয়ে পড়ব।
printf(“Hello world!”); বা return 0; এ গুলোকে বলে স্টেটমেন্ট (Statement)। প্রতিটি স্টেটমেন্টের শেষে একটি করে সেমিকোলন (;) দিতে হয়। আমরা যদি সেমিকোলন না দিয়ে থাকি তাহলে কম্পাইলারে ভুল দেখাবে এবং প্রোগ্রামটি রান হবে না। প্রোগ্রামিং এর শুরুর দিকে অনেকেই সেমিকোলন দিতে ভুলে যায়,তখন কম্পাইল এরর (compile error) দেখায়, পরে কোথায় ভুল হয়েছে খুজে বের করার চেষ্টা করে। একটু খেয়াল করে কোড লিখলে এসব ছোটখাটো ভুল গুলো সহজেই এড়ানো যায়।
এবার এ প্রোগ্রামটি নিজে নিজে লিখতে চেষ্টা করুন। Hello world! এর পরিবর্তে আপনার নাম বা ইচ্ছে মত কিছু দিয়ে রান করার চেষ্টা করুন।

সমস্যা এবং সমাধানঃ
কোড ব্লক একটা IDE. এটার সাথে আমাদের কম্পাইলার লাগে। যেটা আমাদের সি প্রোগ্রাম গুলোকে কম্পাইল করবে। যদি কম্পাইলার ইন্সটল না থাকে, তাহলে নিচের মত ইরর দেখাবে।
Environment Error Can’t fild compiler executable in your configurd search path for “GNU GCC” compiler

এ জন্য আমাদের Codeblocks with Mingw সহ ডাউনলোড করে ইন্সটল করতে হবে। ডাউনলোড পেইজে গিয়ে codeblocks-x.x.x mingw-setup.exe টা ডাউনলোড করে ইন্সটল করে নিলেই এ সমস্যার সমাধান হবে। 

ডেটা টাইব এবং ভ্যারিয়েবল ঃ
ডেটাএর আগের প্রোগ্রামে আমরা মাত্র এক লাইন এর একটা আউটপুট দেখিয়েছি। যা শুধু মাত্র প্রোগ্রামিং শুরু করার জন্যই যথেষ্ট ছিল। বাস্তবে আমাদের জটিল কিছু প্রোগ্রাম লিখতে হবে। যার জন্য দরকার আমাদের ভ্যারিয়েবল এর ধারনা।
ভ্যারিয়েবল হচ্ছে একটি নাম, যা দিয়ে কম্পিউটারের মেমরিতে কোন ডেটা রাখা হয়। এ ডেটা হতে পারে নিউম্যারিক (যে কোন সংখ্যা) অথবা একটি character মান। এ ভ্যারিয়েবল এর মধ্যে কি ধরনের ডেটা রাখব আমরা তাই হচ্ছে ডেটা টাইপ। ভ্যারিয়েবল সম্পর্কে আমরা পরে আবার জানব। এবার একটু এ ডেটা টাইফ সম্পর্কে জানি।
সি প্রোগ্রামিং এ অনেক প্রকারের ডাটা টাইপ আছে। তার মধ্য প্রধান চারটি হচ্ছেঃ
  • int data type
  • char data type
  • float data type
  • double data type

int data type

int data type বলতে integer quantity(অবিভাজ্য সংখা যেমনঃ ১, ২, ৩ ইত্যাদি) বুঝায়। এর সাইজ ২ বাইট বা ১৬ বিট(১বাইট=৮বিট)এবং রেঞ্জঃ -৩২৭৬৮ থেকে +৩২৭৬৭ পর্যন্ত। কিছু কিছু কম্পাইলারে int ডেটার জন্য ৪ বাইট মেমরি দেয়। অর্থাৎ একটা int ডেটা টাইপের জন্য সর্বোচ্চ ৪ বাইট ডেটা রাখা যাবে। যার রেঞ্জ হচ্ছে -2,147,483,648 থেকে 2,147,483,647 এ রেঞ্জ এর মানে হচ্ছে এর থেকে বড় মানের সংখ্যা যদি আমরা ব্যবহার করি তাহলে কম্পাইলার সঠিক মান দিবে না। এ সাইজ এবং রেঞ্জ কম্পাইলার ভেদে ভিন্ন হতে পারে।
int data type এর উদাহরন হিসেবে আমরা একটা প্রোগ্রাম দেখতে পারি। একটি আয়াতাকার জমির দৈর্ঘ্য এবং প্রস্থ জানলে আমরা তার ক্ষেত্রফল বের করতে পারি। তাই না? মনে করে নিচ্ছি দৈর্ঘ্য ৫ একক এবং প্রস্থ ৮ একক। আমরা এর ক্ষেত্রফল হবে ৫*৮ = ৪০ একক। প্রোগ্রামে আমরা কিভাবে তা বের করতে পারি? নিচের প্রোগ্রামটি দেখি।
#include <stdio.h>

int main()
{
 int volume;
 int length = 5;
 int width = 8;
 volume = length * width;
 printf("%f", volume);
 return 0;
}

প্রোগ্রামটি রান করলে আমরা আউটপুট দেখতে পাবো 40
এটা অবশ্যই আমাদের প্রথম প্রোগ্রাম থেকে দেখতে অনেক জটিল। এবং কিছুটা বড়। তবে অবশ্যই অনেক সহজ। কিছুক্ষন আগে আমরা ভ্যারিয়বল নামে একটা বস্তুর নাম শুনছি যা কোন কিছু স্টোর বা সেভ করে রাখে কম্পিউটার মেমরিতে।
আমাদের হিসেব করা জমির ক্ষেত্রফল বের করে ও তো কম্পিউটার মেমরিতে রাখতে হবে। কম্পিউটার মেমরিতে রাখার জন্য আমাদের দরকার একটা ভ্যারিয়েবল। ক্ষেত্রফল রাখার জন্য আমাদের ভ্যারিয়েবল এর নাম দিয়েছি volume, কিন্তু volume এ আমরা কি ধরনের ডেটা রাখব তা কম্পিউটারকে জানতে হবে না? আমরা যেহেতু একটা ক্ষেত্রফল রাখব এবং তা হচ্ছে একটা সংখ্যা।
কিছুক্ষন আগে int নামে আমরা একটা ডেটা টাইপ সম্পর্কে জেনেছি। যা দিয়ে কম্পিউটারে Integer/ পূর্ণসংখ্যা কম্পিউটারে সংরক্ষন করা যায়। তাই আমরা int ব্যবহার করেছি। আর এর সব টুকু লিখছি একটা লাইনের মধ্যে int volume; যাকে বলা হয় ভ্যারিয়েবল ডিক্লারেশন। অর্থাৎ একটা ভ্যারিয়েবল ব্যবহার করার আগে একে ডিক্লেয়ার করতে হয়। ডিক্লেয়ারেশন শেষ আমরা একটা সেমি কোলন দিয়েছি। একটি ভেরিয়েবল ডিক্লেয়ারেশন শেষে তা শেষ করার জন্য একটা সেমিকোলন ব্যবহার করতে হয়। অর্থাৎ একটি ভ্যারিয়েবল ডিক্লেয়ার করতে হয় নিচের মত করেঃ
data_type variable_name;
কম্পিউটারকে তো আমাদের জানাতে হবে যে আমাদের জমির দৈর্ঘ্য এবং প্রস্থ কত, তাই না? এর জন্য আমরা আরো দুটি ভ্যারিয়েবল নিয়েছি length এবং width নামে। এ দুটি আবার int volume; থেকে একটু ভিন্ন। আমরা এ দুটি ভ্যারিয়েবল ডিক্লেয়ার করার সাথে সাথে একটি মান সেট করে দিয়েছি। যাকে বলে ভ্যালু এসাইন করা। মান সহ ভ্যারিয়েবল ডিক্লেয়ার করার নিয়ম হচ্ছেঃ
data_type variable_name = value;

এর পর বর্তীতে আমরা লিখছি volume = length * width; এর মানে হচ্ছে length ভ্যারিয়েবল এর মান এবং width ভ্যারিয়েবল এর মান গুন করে volume এ রাখা।
এর পরবর্তী লাইন এর সাথে আমরা কিছুটা পরিচিত। printf(“%d”, volume); যা হচ্ছে printf() ফাংশন।
printf() ফাংশন এর কাজ হচ্ছে কোন কিছু প্রিন্ট করা। একটা লেখা প্রিন্ট করার জন্য printf() এর ভেতর ডাবল কোটেশন এর মধ্যে কিছু লিখলেই তা প্রিন্ট করে দেয়, তা আমরা এর আগেই জেনে এসেছি।
কিন্তু এবার আমরা একটা ইন্টিজার ভ্যালু প্রিন্ট করব এবং একট ভ্যারিয়েবল এর থেকে। এর জন্য কিছু নিয়ম আমাদের ফলো করতে হবে। একটি ইন্টিজার প্রিন্ট করার জন্য printf() এর ভেতর ডাবল কোটেশন দিয়ে লিখতে হয় %d, এটিকে বলে placeholder। প্রত্যেকটি ডেটা টাইপের জন্য আলাধা আলাধা placeholders রয়েছে। %d মানে হচ্ছে display integer। ডাবল কোটেশনের পর আমরা একটি কমা দিয়েছি। এর পর লিখছি আমাদের ইন্টিজার ভ্যারিয়েবলটি। যা আমাদের জমির ক্ষেত্রফল প্রিন্ট করে দিয়েছে।
এ কাজটা তো আমরা মুখেই করতে পারতাম তাই না? ভালো হতো যদি প্রোগ্রামটা রান হওয়ার পর দৈর্ঘ্য এবং প্রস্থ নেওয়া যেত। তাহলে আমরা যে কোন জমির ক্ষেত্রফল বের করতে পারতাম। আমরা এমন কিছুই শিখব। তার আগে আরো কিছু ব্যাসিক ধারনা নিয়ে নি।


প্লেসহোল্ডার / Placeholder

কিছুক্ষণ আগে আমরা placeholder নামে একটা শব্দ শুনেছি। প্রত্যেকটা ডেটা টাইপের জন্য আলাদা আলাদা প্লেসহোল্ডার রয়েছে। নিচে ভিন্ন ভিন্ন ডেটা টাইপ ও তাদের প্লেসহোল্ডার গুলো দেওয়া হলোঃ
ডেটা টাইপপ্লেসহোল্ডার
int%d
char%c
float%f
double%lf

character data type

এবার আমরা character data type সম্পর্কে একটু জানতে পারি।
char data type বলতে single character( একটি বর্ন যেমন a, b, z, A, N ইত্যাদি) বুঝায়। এর সাইজ ১ বাইট বা ৮ বিট।বিট (১বাইট=৮বিট) এবং রেঞ্জঃ -১২৮ থেকে +১২৭ পর্যন্ত। আমাদের কীবোর্ডের প্রত্যেকটি চিহ্নই এক একটা character। কারেকটার ভ্যারিয়েবল ডিক্লেয়ার করার নিয়ম হচ্ছেঃ
char variable_name;
character ভ্যারিয়েবলে মাত্র একটি কারেকটার / লেটার / বর্ণ সংরক্ষন করা যায়। নিচের প্রোগ্রাম দেখিঃ
#include <stdio.h>

int main()
{
char ch = 'A';
printf("%c", ch);
return 0;
}

এখানে ch নামে একটা কারেকটার ভ্যারিয়েবল নিয়েছি। এরপর তা প্রিন্ট করেছি। ভ্যারিয়েবলের মধ্যে কোন কারেকটার এসাইন করার জন্য তা সিঙ্গেল কোটেশনের মধ্যে রাখতে হয়। এভাবে ‘A’ ।

float data type:

integer ডেটা টাইফে শুধু মাত্র পূর্ণ সংখ্যা গুলো সংরক্ষন করা যায়। আপনি একটা integer ভ্যারিয়েবলে একটি দশমিক মান যেমনঃ ৮.৯ বা ইচ্ছে মত কিছু রাখুন। এর পর ঐ ভ্যারিয়েবলটি প্রিন্ট করুন। কি দেখলেন? দশমিকের পরের অংশ নেই তাই না? নিচের প্রোগ্রামটা আপনি রান করিয়ে দেখতে পারেনঃ
#include <stdio.h>

int main()
{
 int n = 8.9;
 printf("%f", n);
 return 0;
}

এটা শুধু আমাদের 8 দেখাবে। যদিও আমরা ভ্যারিয়েবলটির মধ্যে রেখেছি 8.9 । এর কারন হচ্ছে int শুধু মাত্র পূর্ণ সংখ্যা গুলোকে কম্পিউটার মেমরিতে সংরক্ষিত করতে পারে। দশমিক মান কম্পিউটারে রাখার জন্য আমাদের দরকার আরেকটি ডেটা টাইফ, যার নাম float ।
float data type বলতে floating point number( দশমিক সংখা যেমনঃ ১০.৫, ১.৮, ৫.৬ ইত্যাদি) বুঝায়। floating point ডেটা টাইফ দশমিকের পর ৬ ঘর পর্যন্ত নির্ভুল মান দিতে পারে। উপরের প্রোগ্রামটার ভ্যারিয়েবল n এর Data Type পরিবর্তন করে float দিয়ে রান করিয়ে দেখুনঃ

#include <stdio.h>

int main()
{
 float n = 8.9;
 printf("%d", n);
 return 0;
}

এটি এবার সঠিক মান দিবে।
বৃত্তের ক্ষেত্রফলের জন্য দরকার এর ব্যাসার্ধের মান। ধরে নিচ্ছি একটি বৃত্তের ব্যাসার্ধ 7.6 একক। আমরা এর ক্ষেত্রফল বের করার একটা প্রোগ্রাম লিখে ফেলিঃ
#include <stdio.h>

int main()
{
 float radius = 7.6;
 float area = (radius*radius * 3.1416);
 printf("%f", area);
 return 0;
}

আমরা radius নামে একটা floting point ভ্যারিয়েবল নিয়েছি। এর মধ্যে বৃত্তের ব্যাসার্ধ রেখেছি। area নামে আরেকটি ভ্যারিয়েবল নিয়েছি যার মধ্যে ক্ষেত্রফল বের করে রেখেছি।
আমরা যানি বৃত্তের ক্ষেত্রফল হচ্ছে ব্যাসার্ধ*ব্যাসার্ধ্য * পাই এর মান। তাই লিখছি এবং মানটি প্রিন্ট করেছি।
এর আগে integer এর উদাহরনে printf ফাংশনে placeholder হিসেবে ব্যবহার করেছি %d, floating point এর জন্য placeholder হচ্ছে %f । বাকিটা তো সহজ তাই না?
আমরা জেনেছি যে floating point দশমিকের পর ৬ ঘর পর্যন্ত নির্ভুল মান দিতে পারে। এর থেকে বেশি ঘর পর্যন্ত নির্ভুল মান পেতে হলে আমাদের আরেকটি ডেটা টাইফ ব্যবহার করতে হবে যার নাম হচ্ছে double ।

double data type

double data type বলতে Double precision floating point number বুঝায়।এটা float data type এর মতোই তবে সাইজ বিশাল। এর সাইজ ৮ বাইট বা ৬৪ বিট। এবং এটি দশমিকের পর ১৫ ঘর পর্যন্ত নির্ভুল মান দিতে পারে।

আমরা জানি বৃত্তের পরিধি ও ব্যাসের অনুপাতকে পাই/ Pi [Π] দিয়ে প্রকাশ করা হয়। এটি একটি অমূলদ সংখ্যা। এটিকে দশমিক আকারে সম্পূর্ণ প্রকাশ করা সম্ভব নয়। দশমিকের পর অসীম সংখ্যা রয়েছে, এ জন্য। আমরা যদি float দিয়ে এর মান বের করার চেষ্টা করি, আমরা পাব দশমিকের পর ৬ ঘর পর্যন্ত। কিন্তু double দিয়ে যদি এর মান বের করি, তাহলে পাব দশমিকের পর ১৫ ঘর পর্যন্ত নির্ভুল মান। double এর মান প্রিন্ট বা আউটপুট পাবার জন্য প্লেসহোল্ডার হিসেবে আমাদের lf ব্যবহার করতে হবে। নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>

int main()
{
double pi = 3.14159265358979323846;
printf("%lf", pi);
return 0;
}

এখন যদিও কম্পাইল করে রান করার পর দশমিকের পর ৬ ঘরই দেখাবে। কিন্তু আমরা বলছি ১৫ ঘর পর্যন্ত নির্ভুল মান দিবে। ঠিকই বলেছি। এখন কম্পাইলারকে বলে দিতে হবে কত দশমিকের পর কত ঘর প্রিন্ট করবে। নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>

int main()
{
double pi = 3.14159265358979323846;
printf("%.9lf", pi);
return 0;
}

এখানে আমরা প্লেসহোল্ডারে লিখেছি .9lf । প্লেসহোল্ডারে দশমিক দিয়ে কত ঘর পর্যন্ত প্রিন্ট করবে, তা বলে দিলে তত ঘর পর্যন্তই প্রিন্ট করবে। উপরের প্রোগ্রামটি এখন পাই এর মান দশমিকের পর ৯ ঘর পর্যন্ত প্রিন্ট করবে।
মাথায় দুষ্টু বুদ্ধি খেলা করে তাই না? .9lf এর জায়গায় .50lf দিলে দশমিকের পর ৫০ ঘর প্রিন্ট করবে, তাই তো? হ্যা, ঠিকই .50lf লিখলে ঠিকই দশমিকের পর ৫০ ঘর পর্যন্ত প্রিন্ট করবে। তবে তা আমরা যে রেজাল্ট চাচ্ছি তা পাবো না। ভুল কিছু পাবো। নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>

int main()
{
double pi = 3.14159265358979323846;
printf("%.20f", pi);
return 0;
}

এখানে আমরা পাই এর মান দশমিকের পর ২০ঘর পর্যন্ত দিয়েছি। এরপর আমরা চাচ্ছি ২০ ঘর পর্যন্তই মান পেতে। তাই প্লেসহোল্ডারে .20f দিয়ে বলে দিয়েছি যেন দশমিকের পর ২০ ঘর পর্যন্ত প্রিন্ট করে। কিন্তু দশমিকের পর ১৫ ঘর পর্যন্ত ঠিক মানই প্রিন্ট করেছে। এরপর কত গুলো শূন্য দিয়ে পূরণ করে দিয়েছে। কারণ dobule ডেটা টাইপ দশমিকের পর ১৫ ঘর পর্যন্ত মান ঠিক মত মনে রাখতে পারে।

ডেটা টাইপ এবং তাদের রেঞ্জঃ

শুরুতেআমরা রেঞ্জ নিয়ে কিছু পড়েছি, হয়তো ঠিক মত বুঝতে পারি নি। কিন্তু এবার বুঝেই ছাড়ব। আমরা বলেছি int data type এর সাইজ হচ্ছে ২ বাইট। আমরা জানি এক বাইট সমান ৮ বিট। তাহলে দুই বাইট সমান ১৬ বিট। আর এই ১৬ বিটের মানে হচ্ছে কম্পিউটার (216 -1) = (65536 -1) = 65535 পর্যন্ত নির্ভুল ভাবে সেভ করতে পারবে। মানে আমরা সুন্দর ভাবেই0-65535 পর্যন্ত যে কোন মান একটি ইন্টিজারে সেভ করতে পারব। এখন যদি আমরা এর থেকে বড় কোন মান যেমন। 65538 ইন্টিজার ডেটা টাইপে সেভ করি, কম্পাইলার ঠিক মত মান আমাদের আউটপুট দিতে পারবে না।

আমরা বলেছি যে কিছু কিছু কম্পাইলার ইন্টিজারের জন্য ৪ বাইট মেমরি বরাদ্ধ করে। ৪ বাইট মানে হচ্ছে ৪*৮ বিট। = ৩২ বিট। আর ৩২ বিট মানে আমরা (232 -1) = (4294967296 -১) = 4294967295 পর্যন্ত নির্ভুল মান সেভ করতে পারব ইন্টিজার ডেটা টাইপ হিসেবে। এর থেকে বড় কোন মান যদি ইন্টিজার হিসেবে সেভ করতে চাই, তাহলে ঠিক মত আউটপুট পাবো না। যেটা পাবো সেটা দারুণ। দারুণ কেন বলছি। আগে 4294967295 এর থেকে বড় যে কোন একটা সংখ্যা ইন্টিজার ভ্যারিয়েবল হিসেবে প্রিন্ট করে দেখি। যেমন 6294967295
#include <stdio.h>

int main()
{
 int n = 6294967295;
 printf("%d", n);
 return 0;
}

কি আউটপুট পাচ্ছি? আমি পাচ্ছি 1999999999… যেটা পাওয়ার কথা সেটা পাই নি। কারণ ইন্টিজার ডেটাটাইপে যতটুকু ক্ষমতা তার থেকে বড় মান আমরা সেভ করার চেষ্টা করেছি, তাই।
4294967295 এর পরবর্তি সংখ্যা 4294967296 , এটা প্রিন্ট করে দেখিঃ
#include <stdio.h>

int main()
{
 int n = 4294967296;
 printf("%d", n);
 return 0;
}

আউটপুট পাচ্ছি শূন্য। ০ ।
4294967297 প্রিন্ট করে দেখলে পাবো ১।
#include <stdio.h>

int main()
{
int n = 4294967297;
printf("%d", n);
return 0;
}


এভাবে যদি 4294967298 প্রিন্ট করি, তাহলে পাবো ২। মানে কি দাড়ালো? মানে 4294967295 এর পরের সংখ্যা গুলো প্রিন্ট করার চেষ্টা করলে আবার ০ থেকে প্রিন্ট করা শুরু করে। সুন্দর একটা কারণ আছে। কারণটা কি? চিন্তা করে বের করতে পারেন।

এতক্ষণ আমরা Unsigned ইন্টিজার সম্পর্কে আলোচনা করেছি। Unsigned মানে হচ্ছে সংখ্যাটা কি ধণাত্ত্বক নাকি ঋণাত্ত্বক, তা বলে দি নি। কিন্তু মাঝে মাঝে আমাদের Singed Integer নিয়ে কাজ করতে হবে। মানে আমরা ভ্যারিয়েবল ডিক্লারেশনের সময় বলে দিব সংখ্যাটা কি ধনাত্ত্বক নাকি ঋণাত্ত্বক, তখন আবার রেঞ্জ ছোট হয়ে যাবে। তখন একটি ইন্টিজারের রেঞ্জ হয়ে যাবে -2,147,483,648 থেকে +2,147,483,647। মানে আমরা -2,147,483,648 পর্যন্ত এবং 2,147,483,647 পর্যন্ত ইন্টিজার মান একটা ইন্টিজার ভ্যারিয়েবলে সেভ করতে পারব।
ধণাত্ত্বক হলে কম্পাইলার আউটপুটে + চিহ্ন প্রিন্ট করবে না। কিন্তু ঋণাত্ত্বক হলে তা দেখাবেঃ
#include <stdio.h>

int main()
{
int n = -899;
printf("%d", n);
return 0;
}

উপরে একটি ধণাত্ত্বক সংখ্যা আমরা বলতে পারি Singed Integer ভ্যারিয়েবল তৈরি করা হয়েছে। এবং পরে তা প্রিন্ট করা হয়েছে।

নিচে ভিন্ন ভিন্ন ডেটা টাইপ এবং তাদের সাইজ দেওয়া হলোঃ
ডেটা টাইপসাইজ
int2 bytes
char1 byte
float4 bytes
double8 bytes
বিদ্রঃ এটি কম্পাইলার ভেদে ভিন্ন হতে পারে।
প্রশ্নঃ একটা double ডেটা টাইপ সর্বোচ্চ কত পর্যন্ত সঠিক মান দিতে পারে? 

লাইব্রেরী ফাংশন ঃ
ফাংশান হচ্ছে পুনরায় ব্যবহার যোগ্য কোড ব্লক। যা একটি নির্দিষ্ট কাজ করতে পারে। সি প্রোগ্রামিং এ এমন অনেক গুলো ফাংশন লেখা রয়েছে। যে গুলোকে বলা হয় লাইব্রেরী ফাংশন। যেমন printf একটি ফাংশন, যার কাজ কোন কিছুর আউটপুট দেখা। আমাদের প্রতিটা প্রোগ্রামের শুরুতেই #include<stdio.h> লেখাটি যুক্ত করি। যার মানে আমরা এর আগেই জেনে এসেছি। মানে হচ্ছে Standard Library Functions টি যুক্ত করা। যেমন আমরা printf ব্যবহার করি, এটি হচ্ছে Standard I/O Functions এর একটা ফাংশন। Standard I/O এ আরো কিছু ফাংশন রয়েছে, যেমনঃ scanf(), getchar(), putchar() ইত্যাদি। এ গুলো সম্পর্কে পরবর্তী চ্যাপ্টার গুলো থেকে জানা যাবে।
নিচে কিচু include file এবং তাদের ফাংশন গুলো দেওয়া হলো। প্রতিটি include file এর ব্যবহার সম্পর্কে বিস্তারিত লেখা লিঙ্কে যুক্ত করা হয়েছে। লিঙ্ক থেকে বিস্তারিত উদাহরণ সহ দেখে নেওয়া যাবে।
কোন ফাংশনে যে মান পাস করা হয়, সে গুলোকে বলা হয় আর্গুমেন্ট/Argument। কোন কোন লাইব্রেরী ফাংশন কোন Argument ছাড়াই কাজ করে। কোন কোন ফাংশন একটি Argument নেয়। আবার কোন কোন ফাংশন একের অধিক Argument নিয়ে কাজ করে।

stdio.h: I/O functions:

  1. getchar() returns the next character typed on the keyboard.
  2. putchar() outputs a single character to the screen.
  3. printf() as previously described
  4. scanf() as previously described
নিচের দুইটি লিঙ্ক থেকে getchar & putchar এবং scanf & printf সম্পর্কে বিস্তারিত জানা যাবে।

string.h: String functions

  1. strcat() concatenates a copy of str2 to str1
  2. strcmp() compares two strings
  3. strcpy() copys contents of str2 to str1
String কি, এর লাইব্রেরী ফাংশন গুলো নিয়ে বিস্তারি জানা যাবে এখান থেকেঃ C – Strings / স্ট্রিং

ctype.h: Character functions

  1. isdigit() returns non-0 if arg is digit 0 to 9
  2. isalpha() returns non-0 if arg is a letter of the alphabet
  3. isalnum() returns non-0 if arg is a letter or digit
  4. islower() returns non-0 if arg is lowercase letter
  5. isupper() returns non-0 if arg is uppercase letter

math.h: Mathematics functions

  1. acos() returns arc cosine of arg
  2. asin() returns arc sine of arg
  3. atan() returns arc tangent of arg
  4. cos() returns cosine of arg
  5. exp() returns natural logarithim e
  6. fabs() returns absolute value of num
  7. sqrt() returns square root of num

time.h: Time and Date functions

  1. time() returns current calender time of system
  2. difftime() returns difference in secs between two times
  3. clock() returns number of system clock cycles since program execution

stdlib.h:Miscellaneous functions

  1. malloc() provides dynamic memory allocation, covered in future sections
  2. rand() as already described previously
  3. srand() used to set the starting point for rand()

Assignment অপারেটর ঃ
Assignment operator: কোন মান বা Value কোন Identifier [ভ্যারিয়েবল] এর মধ্যে assign করা বা একটা মান রাখার জন্য জন্য assignment operator ব্যবহৃত হয়। C তে অনেক রকম Assignment operator রয়েছে। যেমনঃ
1) = (Equal to)
2) +=(Plas equal to)
3) -=(Mainus equal to)
4) *=(Product equal to)
5) /=(Division equal to)
6) %= (Mode equal to) etc
তবে সবচেয়ে ব্যবহৃত Assignment operator হচ্ছে = (Equal to)। এটি নিচের from এ লিখা হয়।
Identifier=expression
এখানে Identifier বলতে সাধারনত চলক(variable) কে বুঝানো হয়। আর expression বলতে যে কোন মান যেমন constant বা variable ইত্যাদি কে বুঝানো হয়।
নিচে কিছু Assignment operator এর উদাহরন দেওয়া হলোঃ
  1. X=5;
  2. Y=10;
  3. Pi=3.1416
  4. Z=x+y+pi
এখানে প্রথম উদাহরনে 5 , x এর মধ্য assign হয়েছে। অর্থাৎ x এর মান এখন 5। দ্বিতীয় উদাহরনে 10 , y এর মধ্য assign হয়েছে। অর্থাৎ y এর মান এখন 10. তৃতীয় উদাহরনে 3.1416 , pi এর মধ্য assign হয়েছে। অর্থাৎ pi এর মান এখন 3.1416. চতুর্থ উদাহরনে (x+y+pi ) , z এর মধ্য assign হয়েছে। অর্থাৎ z এর মান এখন (x+y+pi ) ।
আমরা এর আগেই assignment operator ব্যবহার করে এসেছি।
আগের একটি প্রোগ্রামই দেখি, যেখানে আমরা আয়াতাকার জমির আয়তন বের করেছি।
#include <stdio.h>

int main()
{
 int volume;
 int length = 5;
 int width = 8;
 volume = length * width;
 printf("%d", volume);
 return 0;
}
যেখানে length নামক একটি ভ্যারিয়েবল এ আমরা একটি মান [5] রেখেছি। এবং width ভ্যারিয়েবলে রেখেছি 8.
+= (Plas equal to) Assignment operator:
এটা নিচের মতো করে লেখা হয়
Expression1 += Expression2;
যা (Expression1 = Expression1 + Expression2 ) এর সমান।
ব্যাখ্যাঃ মনে করি x=3 , y=5.
যদি লেখা হয়: x+=y তাহলে x এর মান হবে x=x+y অর্থাৎ x=8.
#include <stdio.h>

int main()
{
 int x =3;
int y = 5;
x +=y;
printf("%d", x);
return 0;
}
উপরের প্রোগ্রামটা রান করিয়ে দেখলে আমরা আউটপুট পাবোঃ 8
নিচের প্রোগ্রামটা দেখিঃ
#include <stdio.h>

int main()
{
 int x =3;
int y = 5;
x = x+y;
printf("%d", x);
 return 0;
}
এ প্রোগ্রামও রান করিয়ে দেখলে আমরা আউটপুট পাবোঃ 8
আউটপুটে কোন পার্থ্যক্য নেই। কম কোড লেখার জন্য প্রায় সময়ই += অপারেটর ব্যবহার করা হয়।
-= (Mainus equal to) Assignment operator
-= এর ক্ষেত্রে নিচের মতো করে লেখা হয়
Exprission1 -= Expression2;
যা (Expression1 = Expression1 – Expression2 ) এর সমান।
ব্যাখ্যাঃ মনে করি x=8 , y=5.
যদি লেখা হয়ঃ x-=y তাহলে x এর মান হবে x=x-y অর্থাৎ x=3.
#include <stdio.h>

int main()
{
 int x =8;
int y = 5;
x -=y;
printf("%d", x);
return 0;
}
উপরের প্রোগ্রামটা রান করিয়ে দেখলে আমরা আউটপুট পাবোঃ 3
নিচের প্রোগ্রামটা দেখিঃ
#include <stdio.h>

int main()
{
 int x =8;
int y = 5;
x = x-y;
printf("%d", x);
return 0;
}
এ প্রোগ্রামও রান করিয়ে দেখলে আমরা আউটপুট পাবোঃ 3
উপরের প্রোগ্রামের সাথে আউটপুটে কোন পার্থ্যক্য নেই। += অপারেটর এর মতই কম কোড লেখার জন্য প্রায় সময় -= ব্যবহার করা হয়।
একই ভাবে *= এর মানে হচ্ছেঃ
Exprission1 *= Expression2;
যা (Expression1 = Expression1 * Expression2 ) এর সমান।
/= এর মানে হচ্ছেঃ
Expression1 /= Expression2;
যা (Expression1 = Expression1 / Expression2 ) এর সমান।
%= এর মানে হচ্ছেঃ
Expression1 %= Expression2;
যা (Expression1 = Expression1 % Expression2 ) এর সমান।

গাণিতিক অপারেটর ঃ
পাটি গণিতে আমরা যে সকল Operators ব্যাবহার করছি তাই হল Arithmetic Operators। যেমন যোগ, গুন, ভাগ ইত্যাদি।
Operatorব্যাবহার
+যোগ
বিয়োগ
*গুণ
/ভাগ
%ভাগশেষ

যোগ, গুন, ভাগ ইত্যাদির তো উদাহরণ দেওয়ার কিছুই নেই, আমরা ইচ্ছে করলেই পারি তাই না? উপরের সকল Operator সম্পর্কে ই আমরা জানি শুধু %(একে Reminder অথবা Mode বলে) Operator ছাড়া। % এর কাজ একটি উদাহরণ দিয়ে ব্যাখ্যা করি।
মড মূলত ভাগশেষ ভ্যালু। এই Mode (%) নিয়ে কাজ করার একটা সুন্দর নাম রয়েছে, যাকে বলে Modulus Arithmetic। Mode এর অনেক কাজ রয়েছে।
বাস্তব একটা উদাহরন দেওয়া যাক।
আমরা সময় হিসেব করি, তা একটা মডুলাস এরিথম্যাটিক বা মডুলাস পাটীগণিত। আমরা যদি ১২ ঘন্টার ঘড়ির কথা চিন্তা করি, তাহলে দেখব ১২ এর পর ১৩ না হয়ে ১ টা ধরি আমরা। আর ঘড়ির এই হিসাবকে বলা যায় ১২ এর মডুলাস এরিথম্যাটিক। আমরা করি কি, প্র্যতকটা ঘন্টাকে ১২ দিয়ে ভাগ করে দি। ১ টা বাজলেও ১২ দিয়ে ভাগ করি। ২ টা বাজলেও। তেমনি ১৫টা বাজলেও। তো যখন ১৫টা বাজে, তখন আমরা মুলত দেখি (১৫%১২) = ৩ বা তিনটা। আস্তে আস্তে আমরা এরকম অনেক গুলো মডুলাস এরিথম্যাটিক নিয়ে কাজ করতে পারব।
মূলত মডের কাজ হচ্ছে একটা লিমিট সেট করে দেওয়া। ঐ লিমিট ক্রস করলে আবার প্রথম থেকে কাউন্ট শুরু হবে। ঘড়ির টাইমের ক্ষেত্রে যেমন, তেমনি।
২৪ ঘন্টার ঘড়ি গুলোতে ২৪ হচ্ছে সর্বোচ্চ ভ্যালু। তো ২৪ এর পর ২৫ না হয়ে হয় (২৫%২৪) = ১।
১৫%৪ = কত হবে?
১৫%৪ এটার উত্তর হবে ৩ কারন ১৫ কে ৪ দ্বারা ভাগ করলে ভাগশেষ থাকে ৩।
মড এর মান সব সময় পূর্ন সংখা হবে। অর্থাৎ ১৫.৫%৪ এর ভাগ শেষ হচ্ছে ৩.৫ কিন্তু এর মান হবে ৩।
মড সব সময় পজেটিভ হবে। ১৫%-৪ এর মান হবে ৩। -১৫%৪এর মান হবে -৩। -১৫%-৪এর মান হবে-৩। ইত্যাদি।
নিচের প্রোগ্রামটা দেখিঃ


#include <stdio.h>
int main()
{
    int x =11%3;
    printf("%d", x);
    return 0;
}

11 কে ৩ দিয়ে ভাগ করলে ভাগশেষ ২ থাকার কথা, তাই না? তাই আমাদের পোগ্রামের আউটপুট হচ্ছে। 2
#include <stdio.h>
int main()
{
    int x =12%3;
    printf(“%d”, x);
    return 0;
}
                
12 কে 3 দিয়ে ভাগ করলে ভাগশেষ ০ থাকার কথা, তাই আমাদের আউটপুটও ০;

ইউনারি অপারেটর ঃ
Unary Operators: C Programming Language এ যে সকল Operator একটি চলকের উপর কাজ করে নতুন মান দেয় তাদের Unary Operators বলে। সবচেয়ে ব্যবহৃত Unary Operators হচ্ছে – (minus sign). – কোন constant অথবা variable এর আগে বসে শুধু negative মান বুঝায়।
#include <stdio.h>
int main()
{
    int x =-3;
    printf("%d", x);
    return 0;
}

যেখানে x এর মান -3 ;
তবে প্রধান দুটি Unary Operators হচ্ছে Increment operator(++) ও Decrement operator(- -) ।
Increment operator: Increment operator কে ++ চিহ্ন দিয়ে প্রকাশ করা হয়। অর্থাত ++ কে increment operator বলে। এটি একটি variable এর উপর বসে এর মান 1 বাড়িয়ে দেয়। এটি variable এর আগে ও বসতে পারে পরেও বসতে পারে। যেমনঃ মনে করি x একটি variable যার মান 5 । ++X এর মান হবে 6 । তেমনি X++ মান ও হবে 6 ।
#include <stdio.h>
int main()
{
     int x =6;
     x++;
    printf("%d", x);
    return 0;
}

উপরে আমাদের x এর মান 6, এর পর আমরা এর মধ্যে চ্ছে Increment operator(++) ব্যবহার করেছি। এবং শেষে তা প্রিন্ট করেছি। আমরা আউটপুট পেয়েছি 7.
এখন যদি আমরা x আগে ++ দিয়ে প্রিন্ট দি, তাহলেও আমরা একই মান পাবো।
#include <stdio.h>
int main()
{
     int x =6;
     ++x;
    printf("%d", x);
    return 0;
}

তবে x++ এবং ++x এর মধ্যে একটু পার্থ্যক্য রয়েছে।
x++ এর মানে হচ্ছে আগে x এর মান এক্সিকিউট হবে এবং তারপর এর মান ১ বাড়বে। আর ++x এর মানে হচ্ছে আগে এর মান এক বাড়বে এবং পরে এক্সিকিউট হবে। এখনো যদি বুঝতে অসুবিধে হয় সমস্যা নেই। নিচের প্রোগ্রামটা দেখিঃ
#include <stdio.h>
int main()
{
     int x =3;
     int y =6;
    printf("%d \n", x++);
    printf("%d \n", ++y);
    return 0;
}

উপরের প্রোগ্রামটা যদি আমরা রান করি, তাহলে আমরা আউটপুট পাচ্ছি 3 এবং 7। Increment operator ভ্যারিয়েবল এর পরে রয়েছিল, আমাদের printf ফাংশন আগে x এর মানটা প্রিন্ট করেছে, এর পর এর মান এক বাড়িয়েছে। তাই আমরা আউটপুট পাচ্ছি 3.
কিন্তু y এর ক্ষেত্রে আগে y এর মান এক বাড়িয়েছে, এবং পরে এর মান প্রিন্ট করেছে। তাই আমরা আউটপুট পেয়েছি 7
এখানে দুটা ভ্যারিয়েবল নিয়েছি, এবং পরে তাদের প্রিন্ট করেছি। একটার আগে ++ ব্যবহার করেছি একটার পরে।
Decrement operator: – – [Minus Minus] কে Decrement operator বলে। এটি একটি variable এর উপর বসে এর মান 1 কমিয়ে দেয়। এটি variable এর আগে ও বসতে পারে পরেও বসতে পারে। যেমনঃ মনে করি x একটি variable যার মান 5 । – -X এর মান হবে 4 । তেমনি X- – মান ও হবে 4 ।
#include <stdio.h>
int main()
{
     int x =6;
     x--;
    printf("%d", x);
    return 0;
}

উপরের প্রোগ্রামে আমরা x এর মান সেট করেছি 6 এবং পরে Decrement operator এর উপর প্রয়োগ করেছি। এর পরে এর মান এক কমে গিয়েছে। আমরা পরে x এর মান প্রিন্ট করেছি এবং এর মান পেয়েছি 5.

লজিক্যাল অপারেটর ঃ
Relational and Logical Operators গুলো হল:
  1. Relational Operators
  2. Equality Operator
  3. Logical Operator

C programming language এ চার প্রকার Relational Operator রয়েছে:
OperatorMeaning
<Less then
<=Less then or equal to
>Greater then
>=Greater then or equal to
মনে করি x, y দুটি চলক। x এর মান 5, y এর মান 6। সুতরাং x<y এর মানে হচ্ছে x y থেকে ছোট অর্থাৎ x<y expression টি সত্য এবং এর মান হবে 1. আবার x>y expression টি মিথ্যে এবং এর মান হবে 0.
Relational Operator ব্যবহার করে আমরা সহজেই দুটি সংখ্যার মধ্যে কোনটা ছোট তা বের করে ফেলতে পারি। যা আমরা এর পরের অধ্যায় if – else অংশে দেখব।

Equality Operator:
RELATIONAL OPERATOR এর সাথে সম্পর্ক যুক্ত দুটি Equality Operator রয়েছে। নিচে এদের দেওয়া হলঃ
OperatorMeaning
==Equal to
!=Not Equal to
এখানে প্রথম টি হচ্ছে দুটি সমান চিহ্ন। দুটি মিলেই Equal to Operator প্রকাশ করে। দ্বিতীয় টি হচ্ছে একটি !(উচ্চারন নট) ও একটি সমান চিহ্ন নিয়ে Not Equal to Operator প্রকাশ করে।
উদাহরনঃ মনে করি x, y দুটি চলক। x এর মান 5. Y এর মান 6। সুতরাং x==y এর মানে হচ্ছে x এবং y এর মান সমান। কিন্ত আমদের x এবং y এর মান সমান নয়। সুতরাং x==y expression টি মিথ্যে এবং এর মান হবে 0. আবার x!=y (উচ্চারন x not equal to y) হয় তাহলে expression টি সত্য হয় এবং এর মান হবে 1.
এখানে মনে রাখতে হবে যে Assignment operator = এবং Equality Operator == সম্পূর্নই ভিন্ন। কোন মান বা Value কোন Identifier এর মধ্যে assign বা নির্দিষ্ট করার জন্য assignment operator ব্যবহৃত হয়। আর যেখানে দুইটা Expression এর মান সমান হলে Equality Operator == ব্যবহার করা হয়। Equality Operator দ্বারা Logical True অথাবা False নির্নয় করা হয়।
এখানে একটার স্থানে আরেকটা কোন অবস্থাতেই বসানো যাবেনা। তাহলে Program এ বিশাল ভুল আসবে। প্রথম প্রথম অনেকেই এই ভুল করে।
LOGICAL OPERATOR:
C প্রোগ্রামিং এ দুটি Logical Operator রয়েছে। তাদের নিচে দেওয়া হলঃ
OperatorMeaning
&&And
||Or
&& কে বলা হয় Logical and এবং || কে বলা হয় Logical Or.
&&(পড়া হয় And) operator :
মনে করি x,y,z তিনটি চলক। এখন (x<y)&& (y<z) হচ্ছে একটি expression. এখন এর মান সত্য হবে যদি (x<y) এবং (y<z) সত্য হয়। (x<y) এবং (y<z) এর যে কোন একটি মিথ্যা হলে (x<y)&& (y<z) এর মান মিথ্যে হবে।
||(পড়া হয় Or Or) operator :
মনে করি x,y,z তিনটি চলক। এখন (x<y)||(y<z) হচ্ছে একটি expression. এখন এর মান সত্য হবে যদি (x<y) এবং (y<z) সত্য হয়। অথবা (x<y) এবং (y<z) এর যে কোন একটি সত্য হয়। (x<y) এবং (y<z) দুটি একসাথে মিথ্যা হলে (x<y)||(y<z) এর মান মিথ্যে হবে।
RELATIONAL AND LOGICAL OPERATORS এর কয়েকটি উদাহরন নিচে দেওয়া হল:
মনে করি x, y, z তিনটি চলক। x এর মান 5. y এর মান 6 এবং z এর মান 7।
Expressionব্যাখ্যামান
X<yTrue1
X==5True1
y==4False0
(X+y)>zTrue1
(X+y)<=zFalse0
X!=yTrue1
(X<y)&&(y==6)True1
(X<y)&&(z!=y)True1
(X>y)||(z!=y)True1
(X>y)&&(z!=y)False0
(X<y)&&(z==y)False0
(X<y)||(z==y)True1

অর্থাৎ সকল true এর মান 1 এবং false এর মান ০।

কন্ডিশনাল অপারেটর ঃ
Conditional Operator: একটা condition দিয়ে দুটি মান select করার একটা পদ্ধতি। এটি নিচের মতো করে লেখা হয়ঃ
Expression1? Expression2: Expression3
যেমনঃ
মনে করি i=5, তাহলে নিচের Conditional Operator টা দেখিঃ
Z=(i<8)?10:100;
        
এখানে Z এর জন্য Conditional Operator টা লেখা হয়েছে। এখানে লিখা হয়েছেঃ Z=(i<8)?10:100; অর্থাত যদি i এর মান 8 থেকে ছোট হয় তাহলে Z এর মান হবে 10। আর তা না হলে z এর মান হবে 100. আমি নিচের প্রোগ্রামে সব কিছু বুঝানোর চেষ্টা করছিঃ if-else statement এর পরিবর্তে Conditional Operator (?:) ব্যবহার করে সহজেই দুইটি statement অথবা valu এর মধ্যে তুলনা করে একটি মান নির্বাচিত করা যায়। Conditional Operator সি প্রোগ্রামিং এ নিচের মত করে লেখা হয়ঃ condition ? first_expression : second_expression; এখানে condition হচ্ছে যে কোন একটা শর্ত। যা সত্য হলে first_expression নির্বাচিত হবে। আর কন্ডিশন ভুল হলে second_expression। নিচে ছোট্ট একটা প্রোগ্রাম। যা দিয়ে দুটি সংখ্যার মধ্যে বড়টা নির্বাচিত করা হয়েছে।
#include <stdio.h>
int main()
{
    int x, y , result;
    scanf("%d %d", &x , &y);
    result = (x>=y) ? x : y ;
    printf("max is %d", result);
    return 0;
}
            
একই প্রোগ্রাম, কন্ডিশন পরিবর্তন করে দুটি সংখ্যার মধ্যে ছোটটা নির্বাচিত করা হয়েছে।
#include <stdio.h>

int main()
{
    int x, y , result;
    scanf("%d %d", &x , &y);
    result = (x<=y) ? x : y ;
    printf("min is %d", result);
    return 0;
}
যদিও একই কাজ if -else বা অন্য অনেক ভাবে করা যায়।

getchar & putchar :
এতক্ষন পর্যন্ত আমরা একটি ডেটা শুধু আউটপুট দিয়েছি। কিন্তু আমাদের প্রোগ্রামে আমরা শুধু কিছু মান আউটপুটই নিব না, ব্যবহারকারী থেকে কিছু ইনপুটও নিতে হবে। ইনপুট এবং আউটপুটের জন্য আজকে দুটি Function নিয়ে আলোচনা করব। একটা হচ্ছে “getchar” আরেকটি হচ্ছে “putchar” Function.

getchar:

getchar Function দ্বারা single character কম্পিউটারে input নেওয়া হয়। এটি একটি C library Function. এটি সাধারণত নিছের মত করে লিখা হয়।
character variable = getchar(); 
getchar Function হচ্ছে স্টান্ডার্ড C I/O library এর একটি অংশ। এটি ইনপুট ডিভাইস যেমন Keyboard থেকে একটি সিঙ্গেল Character দেয়। প্রোগ্রামের মঝে এটি নিচের মত করে লিখা হয়ঃ
char x;
x = getchar();
এখানে char x; দ্বারা বুঝানো হয়েছে যে এটি একটি character type Variable. পরবর্তিতে x= getchar(); দ্বারা x এর মান ইনপুট ডিভাইস [ কীবোর্ড ] হতে নিবে। নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>

int main()
{
    char x;
    printf("Enter a character: ");
    x = getchar();
    return 0;
}
উপরের প্রোগ্রামটা রান করুন এবং কীবোর্ড হতে একটি বর্ণ টাইপ করে এন্টার কী প্রেস করুন। কোন আউটপুট পাচ্ছি না। কারণ আমরা ইনপুট নিয়েছি। আউটপুট দি নি। আউটপুটের জন্য আরেকটা ফাংশন ব্যবহার করব। putchar

putchar Function:

putchar Function দ্বারা single character কনসোলে দেখানোর জন্য ব্যবহার করা হয়। এটি getchar Function অনুরুপ। এটি সাধারনত নিছের মত করে লিখা হয়।
putchar(character variable );
এটি ও স্টান্ডার্ড I/O library এর একটি অংশ। প্রোগ্রামের মঝে এটি নিচের মত করে লিখা হয়ঃ
char x;
putchar(x);
getchar Function এর মত এখানে char x; দ্বারা বুঝানো হয়েছে যে এটি একটি character type Variable. পরবর্তিতে putchar(x); দ্বারা x এর মান আউটপুট ডিভাইসে দেখাবে।
#include <stdio.h>
int main()
{
     char x;
     x= getchar();
     putchar(x);
     return 0;
}
উপরের প্রোগ্রামে একটি character variable xনিয়েছি। এখন প্রোগ্রামটি রান করার পর আপনি যাই ইনপুট দিবেন, putchar Function দ্বারা আপনাকে দেখাবে।
ছোট অক্ষরকে বড় অক্ষরে পরিনত করাঃ
#include <stdio.h>

int main()
{
     char x;
     x= getchar();
     putchar(toupper(x));
     return 0;
}

এ প্রোগ্রাম এ যে Character ই input হিসেবে নিবে তার Uppercase মানে বড় হাতের অক্ষর Output দিবে। আর বড় হতের দিলে ও বড় হাতের অক্ষর Output দিবে। তবে সংখা দিলে তাই Output দিবে।
এখানে আমরা toupper() নামক লাইব্রেরী ফাংশং ব্যবহার করেছি। নাম থেকেই তো এর কাজ বুঝা যায় তাই না?
বড় অক্ষরকে ছোট অক্ষরে পরিনত করাঃ
#include <stdio.h>

int main()
{
    char x;
    x= getchar();
    putchar(tolower(x));
    return 0;
}


এ প্রোগ্রাম এ যে Character ই input হিসেবে নিবে তার Lowercase মানে ছোট হাতের অক্ষর Output দিবে। আর ছোট হতের দিলে তাই Output দিবে।

scanf & printf :
আমরা এর আগে আমরা একটি মাত্র character কম্পিউটারে কিভাবে getchar এর সাহায্যে input নেওয়া যায় তা দেখছি। এবার আমরা single character, numerical values এবং string কিভাবে কম্পিউটারে input নিব তা দেখবো। single character, numerical values. এবং string যেকোন মান কম্পিউটারে নেওয়ার জন্য “scanf” function ব্যবহার করা হয়। আবার putchar এর মত কোন মান পর্দায় দেখানোর জন্য “printf” function ব্যবহার করি যা আমরা এর আগেই ব্যবহার করা শুরু করেছি। putchar দিয়ে একটি মাত্র character কম্পিউটারে Output দেখানো যেত, কিন্তু “printf” function দ্বারা একদিক ডাটা যেমন single character, numerical values. এবং string ইত্যাদির যেকোন মান কনসোলে আউটপুট দেখানো যায়।

“scanf” function ব্যবহারের নিয়মঃ

scanf(control string, argument1, 
argument2,……..argumentn);

এখানে control string দ্বারা কোন ধরনের Data input নিব তার ফরমেট বুঝায়। আর argumentদ্বারা Data কম্পিউটারে কোথায় (memory address এর কোন জাগায়) সংরক্ষন হবে তা বুঝায়।
যেমন একটি প্রোগ্রামে নিচের মত করে Scanfব্যবহার করা হয়ঃ
char name;
scanf(“%c”,&name);
এখানে name নামে একটি variable নেওয়া হয়েছে। তার পর আমরা এখন ইনপুট ডিভাইস থেকে এ চলকের মান কম্পিউটারে নিব। এ জন্য Scanf(“%c”,&name); statement দিয়ে তা নেওয়া হয়েছে।

এখানে control string হচ্ছে c। প্রতিটি control string একটি % চিহ্ন দিয়ে শুরু করতে হয়। তাই এখানে control string টি %c দ্বারা লিখা হয়েছে।control string কে প্লেসহোল্ডার ও বলা হয়। এখানে c দ্বারা বুঝানো হয় যে Data item একটি single character। এরকম আরো অনেক গুলো control string রয়েছে।
scanf নিয়ে সম্পুর্ণ একটা প্রোগ্রামঃ
#include<stdio.h>
int main()
{
    float gpa;
    printf("Enter your SSC GPA:");
    scanf(“%f”,&gpa);
    printf("You SSC GPA: %f \n",gpa);
    return 0;
}
নিচে এর একটি তালিকা দেওয়া হল।
CodeMeaning
%aInput হিসেবে Floating-point Data item নিতে পারবে।
%cInput হিসেবে একটি মাত্র character Data item নিতে পারবে।
%dInput হিসেবে Decimal integer Data item নিতে পারবে।
%eInput হিসেবে Floating-point Data item নিতে পারবে।
%fInput হিসেবে Floating-point Data item নিতে পারবে।
%gInput হিসেবে Floating-point Data item নিতে পারবে।
%iInput হিসেবে Decimal, Hexadecimal or Octal Integer Data item নিতে পারবে।
%oInput হিসেবে Octal Integer Data item নিতে পারবে।
%pInput হিসেবে Pointer Data item নিতে পারবে।( Pointer সম্পর্কে পরে আলোচনা করা হবে)।
%sInput হিসেবে String Data item নিতে পারবে।
%uInput হিসেবে Unsigned decimal Data item নিতে পারবে।
%xInput হিসেবে Hexadecimal Data item নিতে পারবে।
control string কে কেউ কেউ আবার Placeholder ও বলে থাকে।

“printf” function ব্যবহারের নিয়মঃ

printf(control string, argument1,
argument2,……..argumentn);
এখানে control string দ্বারা কোন ধরনের Data Output দিবে তার ফরমেট বুঝায়। আর argumentদ্বারা প্রতিটি Output Data প্রকাশ করে। এখানে কিন্তু “scanf” function এর মত memory address প্রকাশ করে না।
যেমন একটি প্রোগ্রামে নিচের মত করে “printf” ব্যবহার করা হয়ঃ
char name;
printf(“%c”, name);

এখানে name নামে একটি Character variable নেওয়া হয়েছে। এখন মনে করি name এর মান কম্পিউটারে আছে আমরা তার Output বের করবো। তাই printf(“%c”, name); দ্বারা তা Output ডিভাইসে প্রকাশ করে। এখানে ও control stringহচ্ছে c। scanf এর মর printf এ ও প্রতিটি control string একটি % চিহ্ন দিয়ে শুরু করতে হয়। তাই এখানে control string টি %c দ্বারা লিখা হয়েছে। এখানে c দ্বারা বুঝানো হয় যে Data item একটি single character। scanf ও printf এর control string একই। scanf এর control string দ্বারা কি ধরনের মান ইনপুট নিবে তা বুঝায়, আর printf এর control string দ্বারা কিধরনের মান আউটপুট দিবে তা বুঝায়।
printf ব্যবহার করে আমরা অনেক প্রোগ্রাম লিখেছি। আরেকটা লিখিঃ
#include<stdio.h>
int main(void)
{
    int roll;
    printf("Can you remember your roll no in class one?\nIf yes, please enter: ");
    scanf(“%d”,&roll);
    printf("Your roll was: %d \n",roll);
    return 0;
}
নিচে printf এর control string বা প্লেসহোল্ডার গুলো দেওয়া হল।
CodeMeaning
%aএটি ব্যবহার করলে Floating-point Data item আউটপুট দিবে।
%cএটি ব্যবহার করলে একটি মাত্র character Data item আউটপুট দিবে।
%dএটি ব্যবহার করলে Decimal integer Data item আউটপুট দিবে।
%eএটি ব্যবহার করলে Floating-point Data item আউটপুট দিবে।
%fএটি ব্যবহার করলে Floating-point Data item আউটপুট দিবে।
%gএটি ব্যবহার করলে Floating-point Data item আউটপুট দিবে।
%iএটি ব্যবহার করলে Decimal, Hexadecimal or Octal Integer Data item আউটপুট দিবে।
%oএটি ব্যবহার করলে Octal Integer Data item আউটপুট দিবে।
%pএটি ব্যবহার করলে Pointer Data item আউটপুট দিবে।
%sএটি ব্যবহার করলে String Data item আউটপুট দিবে।
%uএটি ব্যবহার করলে Unsigned decimal Data item আউটপুট দিবে।
%xএটি ব্যবহার করলে Hexadecimal Data item আউটপুট দিবে।
এবার আমরা scanf ও printf এর ব্যবহারের উপর একটি ছোট্ট প্রোগ্রাম দেখিঃ
#include<stdio.h>
int main(void)
{
    char name[80];
    scanf(“%s”,&name);
    printf("You enter: %s",name);
    return 0;
}

এখানে একটি name নামে একটি character array (array সম্পর্কে পরে আলোচনা করা হবে) নেওয়া হয়েছে, যা মোট ৮০ টি character ধারন করতে পারবে(আসলে ৭৯ টি আরেকটি Null Character, যা সম্পর্কে পরে আলোচনা করা হবে) । তার পর এর মান ইনপুট ডিভাইস হতে নেওয়া হবে scanf function দ্বারা। scanf এর ভিতর %s দ্বারা বুঝানো হয়েছে যে এটি একটি String Input নিবে। তার পর এ মান printf(“%s”,name); দ্বারা পর্দায় আউটপুট দেখানো হয়েছে।

if - else :
একটা লজিক্যাল টেস্ট যদি সত্য হয়, তাহলে কিছু কাজ করবে। যদি মিথ্যে হয়, তাহলে অন্য কাজ। এ লজিক থেকেই if else. যেমনঃ যদি আজ শুক্রবার হয়, ঘুমাবো। না হলে ব্যাগ গুছিয়ে স্কুল/কলেজে যাবো। এমন ধরনের “যদি, তা নাহলে” থেকেই if – else।
if(expression) statement 1
else statement2;

এখানে এই statement দিয়ে বুঝানো হয়, যদি Expression টি সত্য হয় তাহলে statement 1 কাজ করবে। আর যদি মিথ্যে হয় তাহলে statement2 টি কাজ করবে।
এখানে করছি কি, আমরা আজকের দিনের প্রথম অক্ষর ইনপুট নিয়েছি এবং তা day নামক ভ্যারিয়েবলে রেখেছি। তারপর if(day==’F’) এখানে একটা লজিক্যাল টেস্ট করেছি। যদি day এর মান F [মানে ফ্রাইডে, শুক্রবার] কারেকটারের সাথে মিলে, তাহলে প্রিন্ট করবে “You can sleep today! :D” কারণ আজ শুক্রবার। আর যদি অন্য কোন কারেকটার ইনপুট দেয়, মানে সপ্তাহের অন্য কোন দিন হয়, তাহলে লেখা উঠবে “oh no! have to go to class :'(”
if – else সহজ, তাই না?
উপরের প্রোগ্রামে হয়তো কেউ কেউ শুক্রবারের প্রথম লেটার হিসেবে F অথবা f যে কোন একটা দিতে পারে। এখন কেউ যদি উপরের প্রোগ্রামে f ইনপুট দেয়, তাহলেও লেখা উঠবে “oh no! have to go to class :'(” । অথচ আজ শুক্রবার। আমাদের প্রোগ্রামটি ঠিক করতে হবে। যেন কেউ F অথবা f যে কোন একটা ইনপুট দিলেই লেখা উঠে “You can sleep today! :D”
তার জন্য নিচের প্রোগ্রাম লিখিঃ
#include<stdio.h>
int main(void)
{
    char day;
    printf("Enter value of X: ");
    scanf(“%c”,&day);
    if((day=='F')|| (day=='f')){
        printf("You can sleep today! :D");
    } else {
        printf("oh no! have to go to class :'( ");
    }
    return 0;
}
আমরা কন্ডিশনটা একটু পরিবর্তন করেছি। লিখছি: if ((day==’F’)|| (day==’f’))
এখানে || মানে or মানে অথবা। আমরা তা লজিক্যাল অপারেটর সেকশনে জেনেছি। এখন (day==’F’) অথবা (day==’f’) যে কোন একটা সত্য হলেই আমাদের প্রোগ্রাম প্রিন্ট করবে “You can sleep today! :D” অন্যথায় প্রিন্ট করবে “oh no! have to go to class :'(”

if -else এ কিন্তু else না থাকলে ও হয়। এটা একটি বাড়তি অংশ। নিচে কয়েকটি statement দেওয়া হলঃ
if (x==1) pfrintf(“%d”,1);

এখানে যদি x=1 হয় তাহলে pfrintf(“%d”,1); statement টি কাজ করবে এবং 1 Print করবে। আর যদি x=1 না হয় তাহলে pfrintf(“%d”,1); statement টি কাজ করবে না। সম্পুর্ণ একটি প্রোগ্রামঃ
#include<stdio.h>
int main(void)
{
    int x;
    printf("Enter value of X: ");
    scanf(“%d”,&x);
    if(x==1){
        printf("value of X is 1");
    } 
    return 0;
}
    if(a>b) printf("a is greater then b");
    else printf("a is less then or equal to b");
এখানে যদি a<b হয়, মানে a যদি b থেকে ছোট হয় তাহলে printf(“a is greater then b”);statement টি কাজ করবে এবং a is grater then b লেখা টি প্রিন্ট করবে। আর যদি a<b না হয় তাহলে printf(“a is greater then b”); কাজ করবে না। else অংশে যাবে এবং printf(a is less then b”); statement টি কাজ করবে তারপর a is less then b লেখাটি প্রিন্ট করবে।
সম্পুর্ণ প্রোগ্রামঃ
#include<stdio.h>
int main(void)
{
    int a,b;
    printf("input the value of a: ");
    scanf(“%d”,&a);
    printf("input the value of b: ");
    scanf(“%d”,&b);
    if(a>b)
        printf("a is greater then b");
    else
        printf("a is less then or equal to b");
    return 0;
}
শুধু মাত্র if statement ব্যবহার করে দুটি সংখ্যার মধ্যে ছোট বড় নির্নয়ের জন্য একটি প্রোগ্রাম লিখিঃ
#include<stdio.h>
int main(void)
{
    int x,y;
    printf("input the value of x: ");
    scanf(“%d”,&x);
    printf("input the value of y: ");
    scanf(“%d”,&y);
    if(x>y)
        printf("x is greater then y\n");
        if(x<y)
        printf("x is less then y\n");
        if(x==y)
        printf("x is equal to y\n");
    return 0;
}
এ প্রোগ্রামে আপনার কাছ থেকে দুটি নাম্বার ইনপুট নিবে। তার পর তাদের মধ্যে কোনটা বড়, ছোট বা সমান তা দেখাবে। If-else statement ব্যবহার করে দুটি সংখ্যার মধ্যে ছোট বড় নির্নয়ের জন্য একটি প্রোগ্রাম লিখিঃ
#include<stdio.h>
int main(void)
{
    int x,y;
    printf("input the value of x: ");
    scanf(“%d”,&x);
    printf("input the value of y: ");
    scanf(“%d”,&y);
    if(x>y)
        printf("x is greater then y\n");
    else
        printf("x is less then y\n");
}
এখানের প্রোগ্রামটি আগের টির মতই। তবে এখানে equality দেখাবে না। equality দেখার জন্য নিচের প্রোগ্রামটি দেখিঃ
#include<stdio.h>
int main(void)
{
    int x,y;
    printf("input the value of x: ");
    scanf(“%d”,&x);
    printf("input the value of y: ");
    scanf(“%d”,&y);
    if(x>y)
        printf("x is greater then y\n");
        if(x==y)
        printf("x is equal to y\n");
    else
        printf("x is less then y\n");
}
পাস এবং ফেল নির্নয় জন্য একটি প্রোগ্রামঃ
#include<stdio.h>
int main(void)
{
    int x;
    printf("input your number: ");
    scanf(“%d”,&x);
    if(x>40 && x<100){
        printf("Congratulation!!! You have passed");
    } else {
        printf("Ops!! You have failed.");
    }
    return 0;
}
এখানে যদি এক্সামের মার্ক ইনপুট দেওয়া হয়ত, তাহলে পাস করছে নাকি ফেল করছে তা দেখাবে।

nested if-else

একটা if ব্লকের ভেতর যদি আরেকটা if/else ব্লক লিখি, তাই হচ্ছে nested if-else। নিচের প্রোগ্রামটি দেখিঃ

#include <stdio.h>
int main ()
{
  int grade;
  printf("Type in your grade: ");
  scanf ("%d", &grade);

  if (grade < 10){
    printf ("Oh no!");
  }
  else{
    if (grade < 40){
      printf ("You failed.\n");
    }
    else{
      printf ("You passed!\n");
      if (grade >= 90){
        printf ("And you got an A!\n");
      }
    }
  }
  return 0;
}
            


while লুপ ঃ
while লুপের সাধারণ ফরম হচ্ছেঃ
while (expression) statement
expression বলতে একটা কন্ডিশন দেওয়া হয়। যতক্ষণ পর্যন্ত এই কন্ডিশনটি সত্য হবে, ততক্ষন পর্যন্ত while লুপটি চলবে। ছোট্ট একটা প্রোগ্রাম লিখিঃ
#include <stdio.h>
int main (){

int number = 0;
while (number <=9){
    printf("%d \n", number);
    number++;
  }
}
            
উপরের প্রোগ্রামে আমরা number নামে একটা ইন্টিজার ভ্যারিয়েবল নিয়েছি। যার প্রাথমিক মান হচ্ছে ০। এরপর আমরা while লুপ লিখছি। (number <=9) এটা হচ্ছে কন্ডিশন। যতক্ষন পর্যন্ত এ কন্ডিশনটা সত্য হবে, ততক্ষণ পর্যন্ত ব্র্যাকেটের ভেতরের {…} কোড গুলো এক্সিকিউট হবে। ব্র্যাকেটের ভেতরে আমরা প্রথমে নাম্বারটি প্রিন্ট করেছি। পরের লাইনে number++; দিয়ে নাম্বারটির মান এক করে বাড়িয়ে দিয়েছি।

প্রথমে number ভ্যারিয়েবলটির ভ্যালু ছিল ০… প্রথমে while লুপের ভেতর ঢুকে নাম্বারটি প্রিন্ট করল। এরপর number++; দিয়ে নাম্বারেরর ভ্যালু এক বাড়িয়ে দিল। এখন number ভ্যারিয়েবল এর মান ১ এরপর আবার লুপের প্রথমে ফিরে গেলো। গিয়ে কন্ডিশনটি (number <=9) চেক করল। number ভ্যারিয়েবলের মান কি ৯ অথবা এর থেকে ছোট? যেহেতু নাম্বার ভ্যারিয়েবলের মান ১, এবং ৯ থেকে ছোট। তাই আবার লুপের ভেতরে ঢুকবে। এবং আবার প্রিন্ট করবে। এবার প্রিন্ট করবে 1. আবার number++; দিয়ে ভ্যালু এক বাড়িয়ে দিবে, মান হবে ২। এবং আবার লুপের প্রথমে গিয়ে চেক করবে। যখন দেখবে ৯ থেকে ছোট, তখন লুপের ভেতরে ঢুকবে। এবং আবার number টি প্রিন্ট করবে। ১০ বার লুপে ঢুকবে।
শেষ বার যখন number++ দিয়ে এক মান বাড়িয়ে দিবে, তখন number ভ্যারিয়েবল এর মান হবে 10 এবং যখন কন্ডিশনটি চেক করবে, তখন দেখবে number ভ্যারিয়েবলের মান ৯ থেকে বেশি। তখন আর while লুপটি কাজ করবে না। প্রোগ্রামটি শেষ হবে।
আমরা আরেকটা প্রোগ্রাম লিখতে পারি। ছোট বেলায় দুষ্টুমি করলে মাঝে মাঝে শিক্ষক বা বাড়িতে তো ১০০ বার লিখতে দিত, “আমি আর দুষ্টুমি করব না।” তখন যদি আমরা প্রোগ্রামিং জানতাম, আমাদের এত কষ্ট করতে হতো না। কয়েক লাইনের কোড লিখলেই ১০০ বার লেখা হয়ে যেতো। চাইলে তখন ১০০০ বার বা ১লক্ষ বার ও লিখে দেওয়া যেত। while লুপ দিয়ে এই প্রোগ্রামটি লিখি। প্রোগ্রামের ভেতর বাংলিশে লিখলাম “ami r dustumi korbo na”
#include <stdio.h>
int main () {

int number = 1;
while (number <=100){
    printf("ami r dustumi korbo na. \n");
    number++;
  }
}
            
প্রোগ্রামটি রান করলে দেখব, কনসোলে ১০০ বার লেখা উঠে, আমি আর দুষ্টুমি করব না।
এখানে এর আগের প্রোগ্রামের মত একই কাজই করা হয়েছে। আগের প্রোগ্রামে নাম্বার ভ্যারিয়েবলটি প্রিন্ট করা হয়েছে। এখন প্রিন্ট করা হয়েছে একটি স্টিং।
প্রতিবার স্টিংটি প্রিন্ট করার পর number ভ্যারিয়েবল এর মান এক করে বাড়িয়ে দেওয়া হয়েছে। এবং while লুপের প্রথমে গিয়ে কন্ডিশনটি চেক করা হয়েছে। যতক্ষন পর্যন্ত দেখল number এর মান ১০০ থেকে ছোট বা সমান, ততক্ষণ পর্যন্ত লুপটি চলেছে। এবং যখনি number এর মান ১০১ এক হয়েছে, তখন লুপের কাজ শেষ হয়েছে।

while লুপ দিয়ে আরেকটি প্রোগ্রাম লিখতে পারি। 1 থেকে 100 পর্যন্ত বেজোড় সংখ্যা গুলো প্রিন্ট করতে পারি। নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>
int main () {

int number = 0;
while (number <=100){
    printf("%d \n", number);
    number = number + 2;
  }
}
            
এক এর থেকে দুই যোগ করলে হবে তিন। একটা বিজোড় সংখ্যা। তিনের সাথে আবার দুই যোগ করলে হবে ৫, আরেকটি বিজোড় সংখ্যা। এভাবে প্রতিবার ভ্যারিয়েবল এর মান দুই বাড়িয়ে দিলেই আমরা বিজোড় সংখ্যা গুলো পেতে পারি। উপরের প্রোগ্রামে সে কাজটিই করা হয়েছে। number = number + 2; দিয়ে প্রতিবার নাম্বার ভ্যারিয়েবলটির মান দুই করে বাড়িয়ে দেওয়া হয়েছে।
প্রথমে ভ্যারিয়েবলটির মান ছিল 1, int number = 1; এর কথা বলছি। এরপর লুপের ভেতরে ঢুকলো। এবং কন্ডিশন চেক করা হল। যেহেতু কন্ডিশন সত্য, তাই লুপের ভেতরের কোড গুলো রান করল। number টি প্রিন্ট করল। পরের লাইনে number ভ্যারিয়েবল টির মান দুই বাড়িয়ে দেওয়া হলো। এভাবে এক সময় যখন দেখল number ভ্যারিয়েবলটির মান 100 থেকে বেশি হয়ে গেলো, তখন লুপটি কাজ করা শেষ করল।


উপরের প্রোগ্রামটিকে একটু মডিফাই করেই তো জোড় সংখ্যা গুলো বের করতে পারি তাই না? তাহলে তা করে ফেলুন।

do - while :
কিছু একটা কর, যতক্ষণ পর্যন্ত একটা কন্ডিশন সত্য হয়। এমন প্রোগ্রাম লিখতে আমরা do while ব্যবহার করি।
do while লুপের সাধারণ ফরম হচ্ছেঃ

do statement while (expression);
expression বলতে একটা কন্ডিশন দেওয়া হয়। যতক্ষণ পর্যন্ত এই কন্ডিশনটি সত্য হবে, ততক্ষন পর্যন্ত এই do while লুপটি চলবে এবং এই statement এক্সিকিউট হতে থাকবে। একটি স্টেটমেন্ট এক্সিকিউট করার জন্য আমাদের দ্বিতীয় ব্র্যকেট ব্যবহার করতে হবে না। কিন্তু যদি আমরা একের অধিক স্টেটমেন্ট এক্সিকিউট করতে চাই, তাহলে আমাদের দ্বিতীয় ব্র্যাকেট ব্যবহার করতে হবে। তখন লিখতে হবে এমন করেঃ
do{
 statement 1;
 statement 2;
 statement 3;
....

} while (expression);

ছোট্ট একটা প্রোগ্রাম লিখিঃ
#include <stdio.h>
int main ()
{
    int number  = 0;
    do {
        printf("%d \n", number);
        number++;
    } while (number <=9);
    return 0;
}
            
উপরের প্রোগ্রামে আমরা number নামে একটা ইন্টিজার ভ্যারিয়েবল নিয়েছি। যার প্রাথমিক মান হচ্ছে ০। এরপর আমরা do while লুপ লিখছি। do এর পর দ্বিতীয় ব্র্যাকেটের মধ্যে আমরা যে স্টেটমেন্ট গুলো এক্সিকিউট করতে হবে, সে গুলো লিখেছি। এরপর লিখছি while (number <=9) এটা হচ্ছে কন্ডিশন। যতক্ষন পর্যন্ত এ কন্ডিশনটা সত্য হবে, ততক্ষণ পর্যন্ত ব্র্যাকেটের ভেতরের {…} কোড গুলো এক্সিকিউট হবে। ব্র্যাকেটের ভেতরে আমরা প্রথমে নাম্বারটি প্রিন্ট করেছি। পরের লাইনে number++; দিয়ে নাম্বারটির মান এক করে বাড়িয়ে দিয়েছি। এরপর এক সময় number এর মান 10 হয়ে গেছে। তখন while (number <=9) এ এসে দেখল কন্ডিশনটি মিথ্যে হয়ে গেছে। মানে number এর মান ৯ এর থেকে বড়, তখন আর do ভেতরে আর ঢুকবে না এবং তার ভেতরের কোড গুলোও এক্সিকিউট করবে না। উপরের প্রোগ্রামটি আমরা আরেকটু ছোট করে লিখতে পারে। একই ভাবে কাজ করবে। শুধু ব্র্যকেটটি সরিয়ে ফেলছি।
#include <stdio.h>
int main ()
{
    int number  = 0;
    do 
        printf("%d \n", number++);
    while (number <=9);
    return 0;
}
            
আমরা যদি একটি মাত্র স্টেটম্যান্ট এক্সিকিউট করতে চাই, তাহলে আমাদের দ্বিতীয় ব্র্যকেট ব্যবহার না করলেও হবে।
do while ব্যবহার করে আমরা কিছু সংখ্যার গড় বের করব। প্রোগ্রামটি প্রথম ব্যবহারকারীকে জিজ্ঞেস করব, কয়টা সংখ্যার গড় ব্যবহার করতে চায়। এরপর এক এক করে সব গুলো সংখ্যা ইনপুট নিবে। তারপর গড় দেখাবে।
#include <stdio.h>
int main ()
{
    int total_no, count = 1;
    float number, average, sum =0;

    printf("How many numbers? ");
    scanf("%d", &total_no);


    do{

        printf("Enter number %d : ", count);
        scanf("%f", &number);
        sum +=number;
        count++;

    }while (count <=total_no);

    average = sum / total_no;
    printf("Average is : %f\n", average);

return 0;
}
            
আমরা অনেক গুলো ভ্যরিয়েবল ডিক্লেয়ার করেছি। total_no হচ্ছে কয়েটা নাম্বারের গড় বের করব, তার জন্য। এরপর আমরা do while লুপে প্রবেশ করেছি। লুপ ততক্ষণই চলবে যতক্ষণ না পর্যন্ত আমাদের সব গুলো নাম্বার ইনপুট নেওয়া হয়। তার জন্য আমরা একটা count ভ্যারিয়েবল নিয়েছি। যার প্রথম মান হচ্ছে ১। এর পর প্রতিবার আমরা একটা সংখ্যা ইনপুট নিব, একবার করে এই count এর মান বাড়িয়ে দিব।
number নামক ভ্যারিয়েবল দিয়ে আমরা এরপর প্রতিটা সংখ্যা ইনপুট নিচ্ছি। ইনপুট নিয়ে সেগুলো সব যোগ করছি। ছোট্ট একটা লাইন দিয়ে। sum +=number; যার মানে হচ্ছে sum = sum + number;

যখন দেখেছি count এর মান total_no এর থেকে বড় হয়ে গেছে, তার মানে হচ্ছে আমাদের সকল সংখ্যা ইনপুট নেওয়া হয়ে গেছে। তাই আমরা do while থেকে বের হয়ে গিয়েছি। এরপর গড় বের করেছি। তারপর প্রিন্ট।

for লুপ ঃ
লুপিং এর কাজে সবছেয়ে বেশি ব্যবহৃত হয় for loop. এ for loop এর তিনটি অংশ রয়েছে। তার আগে আমরা দেখেনি for loop সাধারন ব্যবহার নিয়ম।
for(exprission1;Exprission2;Expression3)Statement
বিদ্রঃ এখানে প্রত্যেকটি Expression ; (সেমিকোলন) দিয়ে আলাদা করে দিতে হবে।
এখানে প্রথম exprission1 হচ্ছে for loop এর প্রথম অংশ। এটি দ্বারা একটি প্রাথমিক মান দেওয়া হয় । যাকে বলা হয় initial অংশ। এটি পুরো লুপিং প্রক্রিয়াকে নিয়ন্ত্রন করে।
দ্বিতীয় অংশটি অর্থাৎ Exprission2 দ্বারা একটি শর্ত দেওয়া হয়। লুপটি কতক্ষন পর্যন্ত চলবে তা এটি নির্নয় করে। Exprission2 তে সাধারনত একটি logical expression থাকে যা শুধু সত্য মিথ্যে বুঝতে পারে। যদি সত্য হয় তাহলে 1 রিটার্ন করে আর যদি মিথ্যে হয় তাহলে 0 রিটার্ন করে। এটি যদি 0 ছাড়া অন্য কোন মান রিটার্ন করে তাহলে লুপটি চলবে, আর যদি 0 রিটার্ন করে তাহলে লুপটি আর চলবে না।
Expression3 কাজ হচ্ছে আমারা প্রথমে যে প্রাথমিক মান নিলাম তাকে আমাদের ইচ্ছে মত মডিফাই করা। এটি প্রত্যেক লুপের শেষ ধাপে কাজ করে।
আর আগেই বলছি লুপটি ততক্ষনই চলবে যতক্ষন পর্যন্ত Exprission2 মিথ্যে বা 0 রিটার্ন না করে।
For loop সম্পর্কে আমরা এতক্ষন অনেক কিছু জানলাম, এবার প্রোগ্রামে এটাকে কিভাবে ব্যবহার করব তা দেখি। তার জন্য একটি প্রোগ্রাম লিখি যা 1 থেকে 10 পর্যন্ত সংখা গুলো প্রিন্ট করবে।
আপনাদের জন্য নিচের প্রোগ্রামটি। এটার আউটপুট কি হবে কিভাবে হবে তা বের করুন।

#include<stdio.h>
int main(void)
{
    int i;
    for(i=0;i<=10;i++)
        printf("%d\n",i);
}
            
এর আউট পুট হচ্ছেঃ ০ 1 2 3 4 5 6 7 8 9 10এখানে আমরা একটি integer variable নিয়েছি। for loop এর প্রথম Expression এ আমরা এর প্রাথমিক মান নিলাম ০. প্রাথমিক মানটি for loop এর দ্বিতীয় অংশ অর্থাৎ logical অংশ দ্বারা যাচাই না হয়েই for লুপের ভেতরে থাকা স্টেটমেন্টটি এক্সিকিউট করবে। এবং প্রথম Expression কাজ শেষ হয়ে যাবে। এর আর কোন কাজ নেই।
Print করার পর এবার তৃতীয় অংশ অর্থাৎ Exprission3 এখানে i++ অংশ দ্বারা মডিফাই হবে। আমরা জানি i++ এর মানে হচ্ছে i = i+1 সুতরাং এখানে i এর মান এক বাড়বে এবং ০ থেকে 1 হবে। এবার দ্বিতীয় অংশ Expression2 এখানে এসে i<=10 অংশ দ্বারা লজিক্যাল যাচাই হবে। এখানে যাচাই করবে যে i এর মান 10 বা 10 থেকে ছোট কিনা। যেহেতু এখন i এর মান ১০ থেকে ছোট তাই লুপটা আবার চলবে। এবং দ্বিতীয় বার এসে 1 প্রিন্ট করবে। আবার Exprission3 তে এসে মডিফাই হবে। আগের লুপ থেকে i এর মান পেয়েছি 1 এখন আবার 1 এর সাথে এক বেড়ে 2 হবে ( এ অংশ i++ দ্বারা) ।
আবার দ্বিতীয় অংশ i<=10 অংশ দ্বারা লজিক্যাল যাচাই হবে। যেহেতু 2, 10 থেকে ছোট তাই আবার 2 প্রিন্ট করবে। এভাবে প্রত্যেক ধাপ শেষ করবে। যখন i এর মান বেড়ে 11 হয়ে যাবে তখন আর লুপ চলবে না। এবং আমাদের প্রোগ্রামটি শেষ হবে। আচ্ছা, আরেকটা প্রোগ্রাম লিখি। ছোট কালে কোন দুষ্টুমি করলে যে আমাদের শাস্তি দেওয়া হতো একশ বার লিখতে, আমি আর দুষ্টুমি করব না। আমরা এবার তা লিখব প্রোগ্রাম লিখে। এবং for লুপ ব্যবহার করে।
#include<stdio.h>
int main(void)
{
    int i;
    for(i=0;i<=100;i++)
        printf("ami r dustumi korbo na. \n");
    return 0;
}
            
এখানে আগের প্রোগ্রামের থেকে একটু পার্থক্য হচ্ছে আগে আমরা i এর মান প্রিন্ট করেছি। এখানে আমরা একটা লাইন প্রিন্ট করেছি “ami r dustumi korbo na.” for লুপ এর ভেতরের Exprission2 তে লিখেছি i<=100। মানে i এর মান যতক্ষণ না পর্যন্ত ১০০ হচ্ছে, ততক্ষণ পর্যন্ত এই লুপটি চলবে। Exprission3 তে i এর মান আমরা প্রতিবার ১ করে বাড়িয়ে দিয়েছি।
এবার আমরা আরেকটি প্রোগ্রাম লিখি। এবার এক থেকে ৫০ পর্যন্ত বেজোড় সংখ্যা গুলো বের করার একটা প্রোগ্রাম লিখি।

#include<stdio.h>
int main(void)
{
    int i;
    for(i=0;i<=50;i++)
        {
        if(i%2==1)
            printf("%d\n",i);
        }
    return 0;    
}
            
আগের প্রথম প্রোগ্রামের মতই i এর মান আমরা প্রিন্ট করেছি। তবে একটা কন্ডিশন দিয়েছি এখানে। for লুপের ভেতর প্রতিবার ঢুকবে। ঢুকার পর if দিয়ে একটা কন্ডিশন চেক করবে। if(i%2==1) মানে হচ্চে i কে দুই দ্বারা ভাগ করলে ভাগ শেষ যদি ১ থাকে, তাহলে if কন্ডিশনের ভেতরের স্টেটমেন্ট printf(“%dn”,i); দিয়ে i এর মান প্রিন্ট হবে। আর না হলে কিছুই হবে না। এখানে কি করছি কি, একটা লুপের ভেতর আরেকটা লুপ ব্যবহার করেছি।
আমরা ইচ্ছে করলে এমন একটা লুপের ভেতর আরেকটা, আরেকটা ভেতর আরেকটা এমন ইচ্ছে মত ব্যবহার করতে পারি। যেমন আমরা এবার একটা for লুপের ভেতর আরেকটা for লুপ ব্যবহার করব। তবে তার আগে উপরের প্রোগ্রামটি আরো সহজে কিভাবে লেখা যায়, তা দেখি। আমরা ইচ্ছে করলে ১ থেকে ৫০ পর্যন বেজোড় সংখ্যা গুলো নিচের মত করেও বের করতে পারিঃ
#include<stdio.h>
int main(void)
{
    int i;
    for(i=1;i<=50;i=i+2)
        printf("%d\n",i);
    return 0;    
}
            
এখানে করছি কি i এর প্রথম মান ধরে নিয়েছি ১। এক একটা বিজোড় সংখ্যা। তা প্রিন্ট করবে। এরপর ১ এর সাথে ২ যোগ করে দিলেই তো হবে ৩, তা বিজোড় সংখ্যা। তা প্রিন্ট করবে। এরপর ৩ এর সাথে ২ যোগ করে দিলে হবে ৫, তা বিজোড় সংখ্যা। তা প্রিন্ট করবে। আমরা লুপের Expression3 তে লিখছি i=i+2। লুপের Expression2 তে কন্ডিশন দিয়েছি i<=50। মানে যতক্ষণ না পর্যন্ত i এর মান ৫০ এর বেশি হবে, ততক্ষন পর্যন্ত লুপটি চলবে।।

এবার একটা for লুপের ভেতরে আরেকটা for লুপ ব্যবহার করে একটা প্রোগ্রাম লিখিঃ
#include<stdio.h>
int main(void){
    int i, j;

    for(i=0;i<=5;i++){
        for (j=0;j<=i;j++){
            printf("%d ", j);
        }
        printf("\n");
      }

    return 0;
}
            
এখানে আমরা দুইটা ভ্যারিয়েবল নিয়েছি। i এবং j. প্রথম for লুপের ভেতর i এর ইনিশিয়াল মান দিয়েছি ০, কন্ডিশন দিয়েছি i<=5 এবং i এর মান 1 করে বাড়িয়েছি। মানে হচ্ছে প্রথম for লুপটি ৫ বার এক্সিকিউট হবে। প্রোগ্রামটি আউটপুট দিবঃ
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
দ্বিতীয় ফর লুপে j=0 দিয়ে ইনিশিয়াল মান দিয়েছি ০, এরপর j<=i দিয়ে কন্ডিশন দিয়েছি। এবং শেষে j++ দিয়ে j এর মান বাড়িয়েছি। কন্ডিশন অনুযায়ী দ্বিতীয় ফরলুপটি কতবার এক্সিকিউট হবে তা নির্ভর করবে প্রথম ফর লুপের উপর। যেমন প্রথম বার i এর মান ০। তাই প্রথমবার দ্বিতীয় ফর লুপ চলবে একবার। দ্বিতীয় বার i এর মান ১, তাই দ্বিতীয় বার দ্বিতীয় লুপ চলবে দুই বার। তৃতীয় বার দ্বিতীয় ফর লুপ চলবে ৩ বার। এবার পঞ্চম বার দ্বিতীয় লুপ চলবে ৫বার। প্রথম বার দ্বিতীয় লুপ প্রিন্ট করবে ০, দ্বিতীয়বার প্রিন্ট করবে 0 1. তৃতীয় বার 0 1 2. এভাবে পঞ্চম বার প্রিন্ট করবে 0 1 2 3 4 5. এখন আমরা যদি প্রথম ফর লুপের কন্ডিশন পরিবর্তন করে দশ করে দি, তাহলে আউটপুট দিবেঃ
do while দিয়ে আমরা কয়েকটা সংখ্যার গড় বের করার প্রোগ্রাম লিখেছি এর আগে। এবার আমরা তা for লুপ ব্যবহার করে লিখবঃ
#include <stdio.h>
int main ()
{
    int total_no, count;
    float number, average, sum =0;

    printf("How many numbers? ");
    scanf("%d", &total_no);

    for(count = 1; count <= total_no; count++){
        printf("Enter number %d : ", count);
        scanf("%f", &number);
        sum +=number;
    }

    average = sum / total_no;
    printf("Average is : %f\n", average);

return 0;
}
            


switch case :
একটা ভ্যালু এর উপর নির্ভর করে অনেক গুলো স্টেটম্যান্ট থেকে একটা স্টেটম্যান্ট এক্সিকিউট করার জন্য switch case ব্যবহার করা হয়। switch case সাধারণত নিচের মত করে লেখা হয়ঃ
switch ( variable ) {
    case expression 1:
        statement;
        break;
    case expression 2:
        statement;
        break;
    case expression 3:
        statement;
        break;
    default:
        statement;
        break;

}
            
এখানে যদি switch ( variable ) এর variable টির মান expression 1 এর সাথে মিলে, তাহলে case expression 1 এর statement এক্সিকিউট হবে। যদি variable টির মান expression 2 এর সাথে মিলে, তাহলে case expression 2 এর statement এক্সিকিউট হবে। যদি variable টির মান expression 3 এর সাথে মিলে, তাহলে case expression 3 এর statement এক্সিকিউট হবে। যদি কোনটির সাথেই না মিলে, তাহলে default এর statement টি এক্সিকিউট হবে। এখানে যত ইচ্ছে তত গুলো case যুক্ত করা যাবে। আর case এর স্টেটম্যান্ট শেষে break; যুক্ত করতে হয়। break; মানে হচ্ছে আমাদের কাজ শেষ, এবার switch case থেকে বের হতে পারি। break; টা খুবি গুরুত্ত্বপূর্ণ।
এখনো একটু জটিল মনে হতে পারে বিষয়টা, আমরা একটা উদাহরন দেখলে অনেক সহজ হয়ে যাবে এই switch case স্টেটম্যান্টটি। আমরা একটা প্রোগ্রাম লিখব এমন, যেখানে যদি আমরা r ইনপুট দি, তাহলে লেখা উঠবে You select Red, যদি w ইনপুট দি, তাহলে লেখা উঠবে You select White. যদি b ইনপুট দি, তাহলে লেখা উঠবে You select Black. আর প্রোগ্রামটা লিখব আমরা switch case ব্যবহার করে।
#include <stdio.h>
int main ()
{
    char colorCode;
    printf("Enter first word of Red, White or Black: \n");
    scanf("%c", &colorCode);


    switch ( colorCode ) {
        case 'r' :
        printf("You select Red.");
        break;

        case 'w':
        printf("You select White.");
        break;

        case 'b':
        printf("You select Black.");
        break;

        default:
        printf("Wrong choose!");
        break;
    }
    return 0;
}
            
উপরের প্রোগ্রামটি রান করি, তারপর r, w, b এ তিনটার মধ্যে যে কোন একটা ইনপুট দিলে ঐ কালারটা দেখবে। আর যদি আমরা অন্য কোন কারেকটার ইনপুট দি, তাহলে লেখা উঠবে Wrong choose!।
switch case এর switch ( colorFirsWord ) এর ভেতরে যে ভ্যারিয়েবলটি রয়েছে, তার মান যদি case ‘r’ এর সাথে মিলে, মানে colorFirsWord এর মান r হয়, তাহলে প্রোগ্রামটি এ স্টেটম্যান্টটি এক্সিকিউট করবেঃ printf(“You select Red.”); এরপরের স্টেটম্যান্ট হচ্ছে break; মানে হচ্ছে আমরা যে কাজ করার জন্য switch case এর ভেতরে প্রবেশ করেছি, তা শেষ হয়েছে। switch case থেকে এবার আমরা বের হতে পারি। break দিয়ে switch case ঐখানেই বন্ধ করে দেওয়া হয়।

একই ভাবে যদি আমরা w ইনপুট দি, তাহলে case ‘r’ এর সাথে মিলিয়ে দেখবে। যেহেতু আমরা w ইনপুট দিয়েছি, প্রথম case এর সাথে মিলে না। পরের case দেখবে। পরের case এ এসে দেখবে case ‘w’ তে ইনপুটির সাথে মিল পেয়েছে, তাই এর পরে থাকা স্টেটম্যান্টটি এক্সিকিউট করবে। printf(“You select White.”); এবং এর পর break দিয়ে switch case থেকে বের হবে।
একই ভাবে আমরা যদি b ইনপুট দি, তাহলে উপরের দুইটা case এ কোন মিল পাবে না, তাই ঐ case গুলোর স্টেটম্যান্ট গুলোও এক্সিকিউট হবে না। শুধু মাত্র case ‘b’ এর স্টেটম্যান্ট গুলো এক্সিকিউট হবে।
যদি আমরা অন্য কোন কারেকটার ইনপুট দি, তাহলে তার জন্য রয়েছে ডিফল্ট ভ্যালু। তখন লেখা উঠবে Wrong choose!
বিদ্রঃ switch ( colorCode ) এর এখানে যে কোন Expression আমরা লিখতে পারি। এমন একটা উদাহরন আমরা দেখব। আবার case এ আমরা একের অধিক স্টেটম্যান্ট লিখতে পারব। তার উদাহরণ একটু পরই দেখব।
উপরের প্রোগ্রামটিতে আমরা যদি বড় হাতে R, W বা B ইনপুট দি, তাহলে লেখা উঠবে Wrong choose!। এখন আমরা উপরের প্রোগ্রামটিকে আরেকটু মডিফাই করব, যেন ছোট বা বড় হাতে colorCode ইনপুট দিলে উভয় ক্ষেত্রেই আমাদের সঠিক আউটপুট দেয়।
#include <stdio.h>
int main ()
{
    char colorCode;
    printf("Enter first word of Red, White or Black: \n");
    scanf("%c", &colorCode);


    switch ( colorCode ) {
        case 'r' :
        case 'R' :
        printf("You select Red.");
        break;

        case 'w':
        case 'W' :
        printf("You select White.");
        break;

        case 'b':
        case 'B' :
        printf("You select Black.");
        break;

        default:
        printf("Wrong choose!");
        break;
    }
    return 0;
}
            
এখানে আমরা লক্ষ্য করলে দেখব আমরা এখন break এর ব্যবহার ছাড়া এক সাথে দুই বার case ব্যবহার করেছি। যেমনঃ
case ‘r’ :
case ‘R’ :

এভাবে break ছাড়া একের অধিক case লিখলে সে গুলো OR অপারেশনের মত কাজ করে। একটা সত্য হলে ঐ case গুলোর পরের Expression গুলো এক্সিকিউট হবে। এবং break পাওয়া পর্যন্ত অপেক্ষা করবে।
switch case এর ভেতরে যে কোন কোডই রান করানো যায়, লুপ চালানো, ফাংশান কল করা সহ সব কিছু। প্রথমে একটা প্রোগ্রাম লিখব, যেখানে switch case এর ভেতরে আমরা একবার for লুপ ব্যবহার করব, একবার while লুপ ব্যবহার করব। এটা বুঝানোর জন্য যে আমরা ইচ্ছে করলে যে কোন কোডই রান করাতে পারি switch case এর মধ্যেঃ
#include <stdio.h>
int main ()
{
    int code;
    int i = 0;
    printf("Enter 1 to print even integers or enter 2 to print odd integers: ");
    scanf("%d", &code);


    switch ( code ) {
        case 1 :
            while(i<=100){
                printf("%d \n", i);
                i=i+2;
            }
        break;


        case 2 :
             for(i =1; i<=100; i=i+2)
                    printf("%d \n", i);

        break;


        default:
        printf("Wrong choose!");
        break;
    }
    return 0;
}
            
প্রোগ্রামটা আমাদের 1 অথবা 2 ইনপুট দিতে বলবে। 1 ইনপুট দিলে ১ থেকে ১০০ পর্যন্ত বেজোড় সংখ্যা গুলো প্রিন্ট করবে। আর 2 ইনপুট দিলে ১ থেকে ১০০ পর্যন্ত জোড় সংখ্যা গুলো প্রিন্ট করবে।
আমরা ইচ্ছে করলে switch case এর ভেতর থেকে ফাংশন ও কল করতে পারি। নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>
int main ()
{
    void playGame(){
       printf("You choose to Play the game.");
        }
    void closeGame(){
       printf("You choose to Close the game.");
        }


int code;

printf("Enter 1 to play the Game.\nEnter 2 to close the Game :");
scanf("%d", &code);


switch ( code ) {
    case 1 :
        playGame();
        break;


    case 2 :
        closeGame();
        break;


    default:
    printf("Wrong choose!");
    break;
}
return 0;
}
            

আমরা দুইটা ফাংশন তৈরি করেছি, playGame() এবং closeGame()। ব্যবহারকারী 1 ইনপুট দিলে playGame() ফাংশনটি কল হবে, এবং 2 ইনপুট দিলে closeGame() ফাংশন কল হবে… এভাবে নিজের মত করে নিজের ক্রিয়েটিভিটি ব্যবহার করে আমরা প্রয়োজন মত আমাদের প্রোগ্রামে switch case ব্যবহার করতে পারি। শুভ প্রোগ্রামিং ☺

ফাংশন ঃ
প্রোগ্রামারদের ম্যাজিক হচ্ছে ফাংশন। এখন আবার আপনার মনে হতে পারে এটা আবার কি? তাই না। মনে করেন আপনি একটা ম্যাজিক শোতে গিয়েছেন। আপনি এখন একটা ম্যাজিক দেখাবেন যেখানে একটা ছেড়া সুতোকে ফু দিলে তা জোড়ালেগে যাবে। এমনই তো দেখেন তাই না? এই ফু টাই হচ্ছে ফাংশন।
তাহলে আমরা এটা কিভাবে লিখব প্রোগ্রামে তা দেখিঃ
সম্পুর্ন সুতো= ফু(ছেড়া সুতো);
অর্থাৎ যাকে ফু দিবেন তা ব্র্যাকেটে লিখতে হয় তাহলে ফু দেওয়ার ফলে কি হয় তা পাওয়া যায়।
এখন ফু শুধু মাত্র ছেড়া সুতো উপর কাজ করে। এখন যদি আপনি ছেড়া সুতোর পরিবর্তে অন্য কিছু যেমন একটা কাগজকে ফু দেন তা কিন্তু টাকাতে পরিনত হবে না। তার জন্য কিছু মন্ত্র পড়তে হবে। এখানে মন্ত্রটা হচ্ছে ফাংশসন।
টাকা = ফু(কাগজ);
কাগজের উপর ফু দিলে তা টাকাতে পরিনত হচ্ছে তাই না? ফাংশনটা ও একই রকম। এই ফু বা মন্ত্র এর মত। এখন আপনাকে বুঝতে হয় কোথায় কি ব্যবহার করতে হবে। অনেক হাবি জাবি বকা হয়ে গেছে এখন দেখি কিভাবে তা আমরা কাজে লাগাবো।
আমরা দুটি সংখা যোগ করতে চাই।
তার জন্য আমাদের যোগ নামে একটা ফাংশন লাগবে।
যোগফল = যোগ(সংখ্যা১, সংখ্যা২);
এখন আপনি হয়তো আমাকে দেখে হাসতে পারেন এত ভেজাল করার কি দরকার। আমি তো এমনিতেই দুটি সংখ্যার মাজে + চিহ্ন দিয়ে যোগ ফল পেতে পারি, মাঝখানে ফাংশন নামক এ বস্তুটা নিয়ে আসার কি দরকার?
আচ্ছা, এটা আমাদের বার বার যোগ করা থেকে বাঁচিয়ে দিব। শুধু মাত্র যোগ ফাংশনটাকে ডাকলেই আমাদের কাজ করে দিব।
আচ্ছা, ফাংশন কি তা আগে জানি। ফাংশন হচ্ছে পুনরায় ব্যবহার যোগ্য কোড ব্লক। যা একটি নির্দিষ্ট কাজ করতে পারে। ফাংশন ভালো ভাবে জানলেই প্রোগ্রামিং এর একটা বিশাল অংশ শেখা শেষ হয়ে যায়। তা জানলেই নিজের ইচ্ছে মত কোড লেখা যায়। সকল প্রোগ্রামিং ল্যাঙ্গুয়েজ এ ফাংশন লেখার ধরন প্রায় একই। আমি সি প্রোগ্রামিং দিয়ে উদাহরন দিচ্ছি।
একটা ফাংশন নিচের মত করে লেখা হয়ঃ
Function_Data_Type Function_Name (Parameters){
....
return value;
 
}
            
  • Function_Data_Type হচ্ছে ফাংশনটি কি ধরনের ডেটা রিটার্ন করবে তা। যেমন int, char, float, double ইত্যাদি।
  • ফাংশানের তো একটা নাম থাকতে হবে তাই না? যে নাম দিয়ে ফাংশনটিকে ডাকতে হবে। Function_Name হচ্ছে ফাংশানের নাম।
  • Parameters হচ্ছে ফাংশন দিয়ে কি কি ডেটা পাস করবে। এখানে এক বা একাদিক Parameter পাস করা যেতে পারে। কোন কোন ফাংশানে কোন Parameter নাও থাকতে পারে। এটা নির্ভর করে কি ধরনের ফাংশন লিখা হচ্ছে তার উপর। একের অধিক Parameter থাকলে তাদেরকে কমা দিয়ে লিখতে হয়।
  • কাজ শেষে ফাংশনটি কি রিটার্ন করবে তাই return দিয়ে পাস করা হয়।
নিচের ছবিটি দেখি। এখানে যোগ করার একটি ফাংশন এবং এর ভিবিন্ন অংশ দেখানো হয়েছেঃ
function add
আমরা ছোট্ট একটা প্রোগ্রাম লিখে ফেলিঃ
#include <stdio.h>
int add(int a, int b){
 
int sum = a+b;
return sum;
}
int main()
{
int x, y , result;
scanf("%d", &x);
scanf("%d", &y);
result = add(x,y);
printf("Result is: %d", result);
 return 0;
}
    
#include <stdio.h> এর পরই আমরা ফাংশনটি লিখছি। main ফাংশন এর আগে। ফাংশনটি কল কছি add(x,y) দিয়ে। যার মধ্যে দুটি প্যারামিটার পাস করেছি। একটা x আরেকটা y, যে গুলো আমরা scanf ফাংশন দিয়ে ইনপুট হিসেবে নিয়েছি। এর ফলে আমাদের প্রোগ্রামটি main থেকে বের হয়ে add ফাংশানের ভেতরে যাবে। গিয়ে কিছু কাজ কমপ্লিট করবে। এবং ফাংশানের ভেতরের কাজ সম্পুর্ন হলে আবার main এ ফিরে আসবে।
এখন ফাংশানে কি করছে জানেন? int a, int b নামক যে ভ্যারিয়েবল লিখছি ফাংশানের argument এ, প্রথম প্যারামিটার মানে x assign হবে a তে। এবং দ্বিতীয়টা মানে y assign হবে b তে। তারপর ফাংশনটি sum নামক ইন্টিজার ভ্যারিয়েবলে a+b এর মান রাখবে। return sum দিয়ে ঐ sum টা রিটার্ন করবে। এবং আমাদের main প্রোগ্রামে ফিরে আসবে। আবার ফাংশানে রিটার্ন করা ভ্যালুটা result নামক ভ্যারিয়েবলে এসাইন করবে।
ছোট্ট একটা যোগের জন্য আসলেই আমরা অনেক ভেজাল করে ফেলছি। তবে এখন আমরা ফাংশন কি তা জানি, কিভাবে কাজ করে তাও জানি।
এবার আরো সহজ একটা ফাংশন লিখি।
#include <stdio.h>
void callme(){
printf("You call me form Main n");
}
int main()
{
callme();
return 0;
}

    
এখানে আমরা callme নামক একটা ফাংশন লিখছি, যা কিছুই রিটার্ন করবে না। এ জন্য ফাংশানের Data Type লিখছি void। আচ্ছা, main থেকে যখন আমরা ফাংশনটিকে কল করছি callme(); দিয়ে তখন ফাংশানের ভেতর গিয়ে দেখে You call me form Main লেখাটি প্রিন্ট করতে। প্রোগ্রামটি তাই করল। এবং callme ফাংশন থেকে বের হয়ে আবার main এ আসল। তারপর দেখল আর কোন কাজ নেই। তাই কি করল? প্রোগ্রামটি শেষ করল।
আমরা আরেকটু কঠিন একটা ফাংশন লিখে ফেলতে পারি না?
আমি কঠিন বলছি তাই বলে মোটেও কঠিন হবে না। এবার আমরা দুটি সংখ্যার মধে বড় সংখ্যাটা বের করার ফাংশন লিখব। তখন কি হবে জানেন? আচ্ছা আগে কোডটি লিখে ফেলিঃ
#include <stdio.h>
int max(int a, int b){
 
int maximum = (a>=b) ? a : b ;
return maximum;
}
int main()
{
int x, y , result;
scanf("%d", &x);
scanf("%d", &y);
result = max(x,y);
printf("max is: %d", result);
 return 0;
}
    
এখানে আমরা max নামে একটা ফাংশন লিখছি। বাকি অংশ আগের মতই। ফাংশানের ভেতর Conditional Operator (?:) ব্যবহার করছি।Conditional Operator সম্পর্কে জানতে লিঙ্কে ক্লিক করে লেখাটি পড়ুন। এর আগে আমরা দুটি সংখ্যা যোগ করছি ফাংশানের ভেতর। এবার দুটি সংখ্যার মধে বড় সংখ্যাটা ফাংশন রিটার্ন করছে। এবং পরে তা আমরা প্রিন্ট করছি।
আচ্ছা, ফাংশন লিখলেই যে রিটার্ন করতে হবে এমন না। ফাংশন কোন কিছু রিটার্ন নাও করতে পারেন। সে ধরনের ফাংশানের Function_Data_Type লিখতে হয় void. আরেকটা ছোট্ট প্রোগ্রাম লিখে ফেলি, কি বলেন?
#include <stdio.h>s
 
void max(int a, int b){
int maximum = (a>=b) ? a : b ;
printf("max is: %d", maximum);
}
 
int main()
{
int x, y;
scanf("%d", &x);
scanf("%d", &y);
max(x,y);
return 0;
}
    
এখানে কি করছি জানেন, আমরা ফাংশনটিকে কল করছি। ফাংশানের ভেতরই বড় ছোট নির্নয় করেছি। ফাংশানের ভেতরই প্রিন্ট করছি। তারপর ফাংশন থেকে বের হয়ে গেছি। মেইন প্রোগ্রামে এসে দেখি আর কোন কাজ বাকি নেই। তাই পোগ্রামটি শেষ হয়েছে।
Factorial কি তা তো আমরা জানি, তাই না? একটি পূর্ণসংখ্যা ও শূন্য থেকে বড় ও সংখ্যাটি থেকে ছোট সকল পূর্ণসংখ্যার গুনফল হচ্ছে ফ্যাক্টোরিয়াল। n পূর্ণসংখ্যা হয়, তাহলে n এর ফ্যাক্টোরিয়াল প্রকাশ করা হয় এভাবেঃ n! যেমন 5! এর মান হবে 120
5! = 5 * 4 * 3 * 2 * 1
একটা পূর্ণসংখ্যার Factorial বের করার একটি প্রোগ্রাম লিখিঃ
#include <stdio.h>
 
long int factorial(int n){
int i;
long int result =1;
if(n>1){
for(i=2; i<=n i++)
result = result*i;
}
return result ;
}
 
int main()
{
int a;
scanf("%d", &a);
printf("Factorial of n is : %d", factorial(a));
return 0;
}
    
এখানে আমরা একটি ফাংশন লিখছি যা ফ্যাক্টোরিয়াল বের করতে পারে। প্যারামিটার হিসেবে আমাদের রয়েছে একটি argument. প্রোগ্রামটি রান করে এর পর http://en.wikipedia.org/wiki/Factorialএখানে গিয়ে ভিবিন্ন সংখ্যার ফ্যাক্টোরিয়াল এর সাথে মিলিয়ে দেখুন আমাদের প্রোগ্রাম কাজ করে কিনা ঠিক মত।
সাথে মিলিয়ে দেখুন আমাদের প্রোগ্রাম কাজ করে কিনা ঠিক মত। বড় সংখ্যার জন্য প্রোগ্রামটি ঠিক মত কাজ করবে না। কেন করবে না? বের করার দ্বায়িত্ব আপনার
আচ্ছা, আমরা এতক্ষন যে ফাংশন গুলো লিখছি তা main এর আগে লিখছি। আমরা ইচ্ছে করলে main এর পরেও লিখতে পারি। তবে তার জন্য main ফাংশন এর আগে তাকে ডিক্লেয়ার করতে হবে। যাকে বলে Function Prototype.
#include <stdio.h>
 
void checkprime(int num);
 
int main()
{
int a;
scanf("%d", &a);
checkprime(a);
return 0;
}
 
void checkprime(int num){
 int i,count=0;
 for(i=2;i<=num/2;i++){
 if(num%i==0){
 count++;
 break;
 }
 }
 if(count==0 && num!= 1)
 printf("%d is a prime number",num);
 else
 printf("%d is not a prime number",num);
}
    
এখানে আমরা প্রাইম নাম্বার চেক করার একটা প্রোগ্রাম লিখছি। এর মধ্যে আমরা checkprime নামক একটা ফাংশন লিখছি যা আমরা main এর পর লিখছি। checkprime নামক যে একটা ফাংশন রয়েছে আমাদের প্রোগ্রামের main এর পর তা আমাদের আগে জানিয়ে দিতে হবে। সে জন্যই Function Prototype. এ জন্য মেইন এর আগে আমাদের ফাংশন প্রোটোটাইপ লিখতে হয়। যেমন আমাদের ফাংশানের প্রোটোটাইপ হচ্ছেঃ void checkprime(int num);
অর্থাৎ Function Prototype লিখতে হবে এমনঃ
Function_Data_Type Function_Name (Parameters);
    
যদিও অনেক কম্পাইলারে Function Prototype লিখতে হয় না।
এই হলো ফাংশন। অনেক সহজ জিনিস, তাই না? আগেই ও বলছি একবার আবার বলি। প্রোগ্রামিং শেখার জন্য অল্প কয়েকটি জিনিস বুঝলেই হয়। ভ্যারিয়েবল, লুপ, ফাংশন আর এরে। এগুলো দিয়েই যে কোন প্রোগ্রাম লিখে ফেলা যায়। দরকার একটু প্র্যাকটিস। আশা করি তা নিয়মিত করবেন।
সবার জন্য শুভ কামনা। শুভ প্রোগ্রামিং।

আ্যারে ঃ
একটা প্রোগ্রামের চিন্তা করি, যেটায় ইউজার থেকে দুইটা নাম্বার নিয়ে যোগ করে তা রিটার্ন / প্রিন্ট করবে বা কনসোলে দেখাবে।
সহজেই আপনি প্রোগ্রামটা লিখে ফেলতে পারবেন তাই না? দুটি ভ্যারিয়েবল নিলাম, তারপর তা যোগ করে প্রিন্ট করলাম। শেষ।
যেমনঃ
#include <stdio.h>
int main(){

int x, y;

    printf("Enter First Number:\n");
    scanf("%d", &x);

    printf("Enter Second Number:\n");
    scanf("%d", &y);

    printf("Addition is %d"
    , (x+y));

    return 0;

}
    
আচ্ছা, যদি তিনটি সংখ্যা যোগ করতে বলে তখন কি করবেন? তিনটি ভ্যারিয়বল নিয়ে তা যোগ করে প্রিন্ট করবেন তাই তো?
আচ্ছা, যদি তিনশ বা তিনহাজার সংখ্যা নিয়ে কাজ করতে হয় তখন কি করবেন? এত গুলো ভ্যারিয়বল কিভাবে লিখবেন? লিখতে কত সময় লাগবে? আর প্রোগ্রামের সাইজ কত বড় হয়ে যাবে না? আরো অনেক গুলো প্রশ্ন জন্ম নিবে এমন সমস্যায়। যাই হোক, প্রোগ্রামিং এসেছে মানুষের সমস্যা কমাতে, বাড়াতে নয়। তাই এর জন্য অনেক সহজ একটা সমাধান আছে। যার নাম Array, অনেক মজার একটা জিনিস।
এখন আমাকে যদি আপনি জিজ্ঞেস করেন Array কি? তাহলে আমি বলব কন্টেইনার। বাক্স। যেটার মধ্যে অনেক কিছু রাখা যায়। বাক্সটা কেমন হবে তা আমরা বলে দিতে পারি। বাক্সটায় কয়েকটা খোপ/প্রকোষ্ঠ থাকবে তা আমরা বলে দিতে পারি এবং বলে দেওয়ার পর তার মধ্যে সুন্দর মত কিছু ডাটা/তথ্য রাখতে পারি।
যেমন আমরা ৩০০টি ভ্যারিয়বল নিয়ে কাজ করব, তখন ঐ কন্টেইনার বা বাক্সে ৩০০টি প্রকোষ্ঠ আমাদের জন্য তৈরি হবে। আর আমরা সুন্দর মত একটা একটা করে ভ্যারিয়বল রাখতে পারব বাক্সের মত দেখতে ঐ Array তে। নিছের ছবিটি দেখুনঃ
one-dimension-array
এটা একটা বাক্সের মত দেখায় না যার মধ্যে ৬টি প্রকোষ্ঠ রয়েছে?
Array কিছুটা এমন। আর এটা দেখতে একটা লাইনের মত তাই না? আর তাই এর নাম Linear Array বা One Dimensional Array.
Array এর ভিতরে যা থাকে তাকে Array Elements বলে। অ্যারেতে সব ধরনের ডাটা রাখা যায়, এমন Integer, Character, Floating Point Number, String ইত্যাদি। Array তে আরেকটা জিনিস আছে, যার নাম হচ্ছে Index. যা দিয়ে আমরা কোন প্রকোষ্ঠে কিছু রাখতে পারব বা কি রাখছি তা বের করতে পারব। প্রতিটা প্রকোষ্ঠের একটা ইনডেক্স থাকে। Array এর প্রথম Element এর Index হচ্ছে ০, দ্বিতীয় Element এর Index বা উপাদানের হচ্ছে ১ , তৃতীয় উপাদানের হচ্ছে ২ ইত্যাদি। এভাবে বাড়তে থাকবে। উপাদানের নাম্বারের থেকে এক কমই হচ্ছে ইনডেক্স নাম্বার। যেমন ষষ্ঠ উপাদানের ইনডেক্স হচ্ছে ০৫।
ইনডেক্স কি তা এখনি পরিষ্কার হয়ে যাবে। মনে করি আমরা Number নামে একটা Array নিয়েছি যার সাইজ হচ্ছে ৬, সাইজ বলতে অ্যারেতে কয়েটা উপাদান থাকবে তা বুঝানো হচ্ছে।
অ্যারে হচ্ছে একটা ভ্যারিয়েবল, যাকিছু ধরে রাখতে পারে সাধারন গাণিতিক ভ্যারিয়েবলের মত। এখন আমরা যদি Number নামক Array তে কিছু রাখতে চাই, তাহলে বলে দিতে হবে কোন ঘরে/ইনডেক্সে রাখব।
যেমন
Number[0] = 77; লিখলে Number Array এর প্রথম ইন্ডেক্সে 77 রেখে দিবে। Number[1] = 11;
লিখলে Number Array এর দ্বিতীয় ইন্ডেক্সে 11 রেখে দিবে। Number[2] = 54;
লিখলে Number Array এর তৃতীয় ইন্ডেক্সে 54 রেখে দিবে।

এভাবে বাকি ইনডেক্সে অন্যান্য সংখ্যা আমরা রাখতে পারব।
আচ্ছা আমরা এখন একটা প্রোগ্রাম চিন্তা করি যেটা ইউজার থেকে ৬টা নাম্বার নিবে এবং পরে তা যোগ করে রেজাল্ট আমাদের দেখাবে। এটা সাধারন পদ্ধতিতে করতে গেলে আমাদের আগে ৬টা ভ্যারিয়েবল নিতে হত, তারপর সেগুলোকে যোগ করতে হত তারপর যোগফল দেখাতে হতো।
এখন আমরা কত সহজেই এ জিনিসটা করতে পারব মাত্র একটি ভ্যারিয়েবল নিয়েঃ
#include <stdio.h>
int main()

{

    int Number[6];
    int i, result=0;

    for(i=0; i< i++){
    printf("Enter %d no Number:\n", i+1);
    scanf("%d", &Number[i]);
    result +=Number[i];
    }

    printf("Result is: %d", result);

    return 0;

}
    
প্রোগ্রামটা আসলে একটা বাজে প্রোগ্রাম। শুধু মাত্র বুঝানোর জন্য এমন ভাবে লেখা হয়েছে। এখানে আমরা একটা Integer Array নিলাম যার Size হচ্ছে 6, অর্থাৎ আমরা এর মধ্যে শুধু মাত্র ৬টি ইলিমেন্ট রাখতে পারব।
scanf(“%d”, &Number[i]); এটা দিয়ে আমরা i এর বর্তমার মান যত তত তম ঘরে ইনপুট নেওয়া মানটি রাখব। প্রথমে i এর মান ধরে নিয়েছি 0, তা Number[0] অর্থাৎ প্রথম ঘরে রানটাইমে আমাদের ইনপুট দেওয়া সংখ্যাটি রাখবে। আমরা যেহেতু লুপ চালিয়েছি এবং প্রতিবার i এর মান এক করে বাড়িয়ে দিয়েছি তাই পরের বার i এর মান হবে 1 এবং Number[1] বা Number Array এর দ্বিতীয় ঘরে রানটাইমে দ্বিতীয়বার ইনপুট দেওয়া আমাদের সংখ্যাটি রাখবে। এভাবে লুপটি ৬ বার ঘুরবে। আমরা বুদ্ধি করে প্রতিবার সংখ্যাটি result +=Number[i] এ লাইনের সাহায্যে ইনপুট নেওয়ার সময় আগের যোগফলের সাথে যোগ করে দিচ্ছি। পরে রেজাল্টি প্রিন্ট করলে আমরা সব গুলো সংখ্যার যোগ ফল পেয়ে যাবো। এখন ইচ্ছে করলে আমরা প্রোগ্রামটি একটু মডিফাই করে কি কি সংখ্যা আমরা ইনপুট দিয়েছি তা বেরও করতে পারব। শুধু মাত্র আরেকটি লুপ চালিয়ে Number Array এর উপাদান গুলো প্রিন্ট করলেই হবে।
#include <stdio.h>
int main()

{

    int Number[6];
    int i, result=0;

    for(i=0; i< i++){
    printf("Enter %d no Number:\n", i+1);
    scanf("%d", &Number[i]);
    result +=Number[i];
    }

    printf("Result is: %d", result);

    return 0;

}
    
Array অনেক প্রয়োজনীয়। অনেক বেশি ব্যবহার এটির।
Array কিন্তু Multi-Dimensional হতে পারে। উপরে আমরা যে উদাহরনটি দেখেছি তা ছিল One-Dimensional এর Dimension সংখ্যা দুই, তিন বা আরো বেশি হতে পারে। Two Dimensional array নিচের মত।
two-dimensionsl-array
এটি একটি Two Dimensional Character Array যার উপাদান সংখ্যা ১২। মনে করি Array টির নাম Character এবং এটিকে লিখতে হবে Character[3][4] এখানে প্রথমটা হচ্ছে row সংখ্যা, দ্বিতীয়টি হচ্ছে Column সংখ্যা। অর্থাৎ এখানে ৩টি রো রয়েছে এবং ৪টি কলাম রয়েছে, সর্বোমোট উপাদাম সংখ্যা হচ্ছে ১২।
প্রথম উপাধান অর্থাৎ উপরের Character নামক Two Dimensional Array থেকেঃ
প্রথম উপাদানটি পেতে হলে আমাদের লিখতে হবে Character[0][0] এবং তা হচ্ছে A
দ্বিতীয় উপাদানটি পেতে হলে আমাদের লিখতে হবে Character[0][1] এবং তা হচ্ছে B
তৃতীয় উপাদানটি পেতে হলে আমাদের লিখতে হবে Character[0][2] এবং তা হচ্ছে C
চতুর্থ উপাদানটি পেতে হলে আমাদের লিখতে হবে Character[0][3] এবং তা হচ্ছে D
পঞ্চম উপাদানটি পেতে হলে আমাদের লিখতে হবে Character[1][0] এবং তা হচ্ছে E
ষষ্ঠ উপাদানটি পেতে হলে আমাদের লিখতে হবে Character[1][1] এবং তা হচ্ছে F
সপ্তম উপাদানটি পেতে হলে আমাদের লিখতে হবে Character[1][2] এবং তা হচ্ছে G
এভাবে আমরা পরের উপাদান গুলোও পেতে পারি।

কোন কিছু রাখতে হলে এ ভাবে একই ধাপ অনুসরন করতে হবে।
প্রথম ইনডেক্সে একটা Character রাখব, তার জন্য লিখতে হবে Character[0][0] আগেই বলেছি Array Index শূন্য থেকে শুরু হয়।
দ্বিতীয় ইনডেক্সে একটা Character রাখার জন্য লিখতে হবে Character[0][1] এভাবে বাকি গুলো রাখতে হবে।
হয়তো প্রথম প্রথম একটু বিদঘুটে লাগতে পারে, দুই একবার ভালো করে পর্যবেক্ষন করলে অনেক সহজ মনে হবে। আর চিন্তা করার সময় যদি বাস্তব জীবনের সাথে মিলিয়ে চিন্তা করা যায় তাহলে আরো দ্রুত বুঝা যাবে।
উদাহরন হিসেবে উপরে আমি সি প্রোগ্রামিং ব্যবহার করেছি। অ্যারের মূল ধারনা এবং ব্যবহার সকল প্রোগ্রামিং এ একই। শুধু মাত্র অ্যারে ডিক্লেয়ার করার পদ্ধতি ভিন্ন।

পয়েন্টার ঃ
পয়েন্টার প্রোগ্রামিং এ দারুন একটি টুল। পয়েন্টার সম্পর্কে জানার আগে কিছু ব্যাসিক জিনিস জানা যাক, যেগুলো বুঝতে কাজে দিবে।
ভ্যারিয়েবল গুলো কিভাবে কম্পিউটার মেমরিতে/ র‍্যাম এ স্টোর হয়?
র‍্যাম এর এক একটি সেল এক একটি বাইট। আর প্রত্যেকটা বাইট এর একটি করে এড্রেস রয়েছে। আর প্রতিটা বাইটে ৮টি করে বিট রয়েছে।
memory-cell-in-ram
আমরা যখন বলি আমাদের র‍্যাম 8 Giga byte, তখন আমাদের কম্পিউটারের র‍্যামে মোট 8 000 000 000 bytes ডেটা স্টোর করা যাবে, এবং এদের প্রত্যেকের একটি করে এড্রেস রয়েছে। প্রথমটি ০ পরের টি 1, এর পরের টির এড্রেস 2 এভাবে বাড়তে থাকে। যদিও কম্পিউটার এ এড্রেস গুলো রিপ্রেজেন্ট করে হেক্সাডেসিমেল নাম্বার সিস্টেমে।
আমরা যখন একটি ভ্যারিয়েবল ডিক্লেয়ার করার পর যখন প্রোগ্রামটি এক্সিকিউট/রান করি তখন কম্পিউটার ঐ ভ্যারিয়েবল এর জন্য কিছু মেমরি এলোকেট করে। কত বাইট মেমরি এলোকেট করবে, তা নির্ভর করে ঐ ভ্যারিয়েবল এর ডেটা টাইপ এবং কম্পাইলার এর উপর।
সাধারনত কম্পাইলার গুলো একটা int এর জন্য 2 byte মেমরি এলোকেট করে। তেমনি একটি char ভ্যারিয়েবলের জন্য 1 byte মেমরি এলোকেট করে। floating-point নাম্বার এর জন্য 4 byte মেমরি এলোকেট করে।
যেমন যখন কম্পিউটার দেখে এমন একটি ডিক্লারেশন int a; তখন এটি বুঝতে পারে এটি একটি ইন্টিজার ভ্যারিয়েবল এবং এর জন্য ২ বাইট মেমরি এলোকেট করা দরকার। তখন র‍্যাম এর খালি যায়গা থেকে এটি এই ইন্টিজারের জন্য ২ বাইট মেমরি এলোকেট করে।
আমরা সহজেই একটি ভ্যারিয়েবলের মেমরি লোকেশন বের করতে পারি, নিচের প্রোগ্রামটি দেখা যাকঃ
#include <stdio.h>
int main()
{
int a =5;
printf("Memory address of variable a is: %x",&a);
return 0;
}
    
উপরের প্রোগ্রামটি রান করালে এমন কিছু দেখাবেঃ Memory address of variable a is: 2686732 । এক কম্পিউটারে এক এক মান দেখাবে। এবং একবার এক এক ভ্যালু দেখাবে। কারণ যতবারই আমরা প্রোগ্রামটি রান করি, প্রতিবারই ভ্যারিয়েবলটির জন্য মেমরিতে একটা জায়গা বরাদ্ধ করা হয়। আর ঐ জায়গার এড্রেসটা প্রতিবারই পরিবর্তন হয়।
কোন ভ্যারিয়েবল এর এর মেমরি এড্রেস জানার জন্য & [ampersend] ব্যবহার করা হয়। যাকে address-of operator [&] ও বলা হয়। যা দিয়ে আমরা অন্য একটি ভ্যারিয়েবল এর এড্রেস বা মেমরি লোকেশন পেতে পারি।
যখন আমরা প্রোগ্রামটি রান করি, তখন কম্পিউটার র‍্যাম এর খালি যায়গা থেকে ভ্যারিয়েবল a এর জন্য ২ বাইট মেমরি এলোকেট করে। কম্পিউটার অটোমেটিকেলি তখন a এর জন্য 2686732 এবং 2686733 নং সেল এলোকেট করে রাখে। আর মেমরি এড্রেস জানার জন্য শুধু মাত্র শুরুর এড্রেস জানলেই হয়। আমরা যখন a এর মেমরি এড্রেস প্রিন্ট করেছি, তখন শুধু শুরুর এড্রেস 2686732 ই পেয়েছি। যদি ও a ভ্যারিয়েবল এর জন্য 2686732 এবং 2686733 মেমরি এলোকেট করা হয়েছে এবং এর মান 5 এই দুই সেলে স্টোর করে রাখা হয়েছে। এখন আমরা যদি a এর মান পরিবর্তন করে অন্য আরেকটা ভ্যালু রাখি, যেমন 8, তখন র‍্যামের 2686732 এবং 2686733 এ দুটো সেল এর মান ও পরিবর্তন হয়ে যাবে এবং এ দুটো সেলে 5 এর পরিবর্থে 8 স্টোর হবে। এবার পয়েন্টার কি জানা যাক।
পয়েন্টার হচ্ছে একটা ভ্যারিয়েবল যার ভ্যালু হচ্ছে আরেকটি ভ্যারিয়েবল এর মেমরি লোকেশন। পয়েন্টার একটা ডেটা, অ্যারে বা ভ্যারিয়েবল এর কম্পিউটার মেমরি লোকেশন রিপ্রেজেন্ট করে বা পয়েন্ট করে। অন্যান্য ভ্যারিয়েবল এর মত পয়েন্টার ভ্যারিয়েবল ব্যবহার করার আগে কম্পিউটার/ কম্পাইলারকে বলতে হবে এটা একটি পয়েন্টার ভ্যারিয়েবল। নিচের মত করে একটি পয়েন্টার ভ্যারিয়েবল ডিক্লেয়ার করে।
data_type *name;
asterisk [*] একটি ভ্যারিয়েবলের আগে ব্যবহার করে পয়েন্টার হিসেবে ডিক্লেয়ার করা হয়। যাকে indirection operator বা value-at-address operator বলা হয়। এখানে আরো কিছু ডেটা টাইপ এর পয়েন্টার ডিক্লারেশন এর উদাহরন দেওয়া হলোঃ
int*ip;/* pointer to an integer */
double*dp;/* pointer to a double */
float*fp;/* pointer to a float */
char*ch /* pointer to a character */
    
আমরা এখন দেখব কিভাবে পয়েন্টার ব্যবহার করতে হয় একটি প্রোগ্রামে।
#include <stdio.h>
int main ()
{
int a = 5; /* variable declaration */
int *ip; /* pointer variable declaration */
ip = &a /* store address of "a" in pointer variable*/
printf("Address of a variable: %xn", &a );
/* address stored in pointer variable */
printf("Address stored in ip variable: %xn", ip );
return 0;
}
    
এখানে আমরা একটি ভ্যারিয়েবল a ডিক্লেয়ার করেছি। এরপর একটি পয়েন্টার ভ্যারিয়েবল ডিক্লেয়ার করেছি। তারপর পয়েন্টার ভ্যারিয়েবলে a এর মেমরি এড্রেস রেখেছি। তারপর & অপারেটর দিয়ে a ভ্যারিয়েবল এর এড্রেস প্রিন্ট করে দেখলাম। এবং পয়েন্টার ভ্যারিয়েবল এর ভ্যালু প্রিন্ট করে দেখলাম। উভয় এর মান ই একই।
আমরা ইচ্ছে করলে এখন ip পয়েন্টার ভ্যারিয়েবল দিয়ে a এর মান বের করতে পারি।
#include <stdio.h>
int main ()
{
int a = 5;
int *ip;
ip = &a;
/* access the value using the pointer */
printf("Value of *ip variable: %dn", *ip );
return 0;
}
    
আমরা যখন প্রগ্রামটি রান করব, তখন ip যে ভ্যারিয়েবলটির এড্রেস শো করবে, তার মান প্রিন্ট করবে। লক্ষকরি, যখন আমরা পয়েন্টার ভ্যারিয়েবল দিয়ে কোন ভ্যারিয়েবল এর এড্রেস বের করতে চাইবো, তখন শুধু পয়েন্টার ভ্যারিয়েবল লিখলেই হবে। কিন্তু যখন আমরা পয়েন্টার ভ্যারিয়েবল দিয়ে মূল ভ্যারিয়েবল এর ভ্যালু বের করতে চাইবো, তখন পয়েন্টার ভ্যারিয়েবল এর আগে * যোগ করতে হবে। যেমন প্রথম প্রোগ্রামে আমরা ip [পয়েন্টার ভ্যারিয়েবল] প্রিন্ট করায় আমরা এড্রেস পেয়েছি। এবং পরের প্রোগ্রামে ip এর আগে একটা * দিয়ে *ip প্রিন্ট করায় আমরা মূল ভ্যারিয়েবলের মান পেয়েছি।

ষ্ট্রাকচার ঃ
Structures সি প্রোগ্রামিং এর দারুণ একটা বিষয়। আমরা ডেটা টাইপ সম্পর্কে জানি, int, char, float ইত্যাদি। Structures দিয়ে আমরা নিজেদের মত করে ডেটা স্ট্রাকচার তৈরি করে নিতে পারি। যেমন অ্যারে হচ্ছে একটা ডেটা স্ট্র্যাকচার। যেখানে শুধু আমরা একই ডেটা টাইপ এর ডেটা রাখতে পারি। কিন্তু স্ট্র্যাকচার তৈরি করে আমরা এক সাথে int, char, float ইত্যাদি ভিন্ন ভিন্ন ডেটা এক সাথে রাখতে পারি। নিজেদের প্রয়োজন মত, ইচ্ছে মত।
int অ্যারেতে শুধু ইন্টিজার ভ্যালুই রাখতে পারব। char অ্যারেতে শুধু কারেকটারই রাখতে পারব। কিন্তু Structures ব্যবহার করে আমরা নিজেদের মত করে ডেটা স্ট্রাকচার তৈরি করতে পারব। এবং ঐখানে ইচ্ছে মত একের অধিক ভিন্ন ভিন্ন ডেটা রাখতে পারব।
Structures নিচের মত করে ডিফাইন করা হয়।
struct book { int no; char name; };

struct কীওয়ার্ড দিয়ে Structures ডিফাইন করা হয়। এরপর লিখছি book, যা হচ্ছে আমাদের নিজস্ব স্ট্র্যাকচারের নাম। এরপর দ্বিতীয় ব্র্যাকেটের মধ্যে স্ট্র্যাকচারের মেম্বার গুলো।
এখানে একটা মেম্বার হচ্ছে ইন্টিজার, যেখানে আমরা বই এর ক্রমিক নাম্বার রাখব। আরেকটা হচ্ছে কারেকটার, যেখানে আমরা বইটির নাম রাখব।
Structures ডিফাইন করার পর তা ব্যবহার করার জন্য ডিক্লেয়ার করতে হয়। একটা ইন্টিজার ভ্যারিয়েবল ব্যবহারের জন্য যেমন আগে তা ডিক্লেয়ার করতে হয়, তেমনি।
ডিক্লেয়ার করার জন্য নিচের মত করে লিখতে হয়ঃ
struct book myBook;

যেখানে struct দিয়ে বুঝায় আমরা একটা স্ট্র্যাকচার ডিক্লেয়ার করতে যাচ্ছি, এরপর book, যা দিয়ে বুঝাচ্ছে আমরা কোন struct টা ডিক্লেয়ার করতে যাচ্ছি। এরপর হচ্ছে আমরা কি নামে আমাদের তৈরি স্ট্র্যাকচারটা ব্যবহার করব।
myBook এর দুইটা মেম্বার। একটা হচ্ছে no আরেকটা name.
এখন আমরা বই এর নাম্বার এবং নাম সেট করব। তার জন্য লিখতে হবেঃ
myBook.no = 3;
myBook.name = ‘C’;

এবার আমাদের সেট করা বই এর নাম এবং নং প্রিন্ট করতে চাইলেঃ
printf("Book No : %dn", myBook.no); 
printf("Book Name : %cn", myBook.name);
    
আমরা ছোট ছোট কোড লিখেছি, এবার পুরো প্রোগ্রামটি লিখে ফেলিঃ
#include <stdio.h>

    struct book{
        int no;
        char name;
        };

int main ()
{
    struct book myBook;
    myBook.no = 3;
    myBook.name = 'C';

    printf("Book No : %d\n", myBook.no);
    printf("Book Name : %c\n", myBook.name);

    return 0;
}
   
typedef ব্যবহার করে আমরা আমাদের স্ট্র্যাকচারের instanc তৈরি করার সময় struct কীওয়ার্ড ব্যবহার ছাড়াই আমাদের তৈরি স্ট্র্যাকচার ব্যবহার করতে পারি। তার জন্য আমাদের উপরের স্ট্যাকচারটা নিচের মত করে লিখতে হবেঃ
typedef struct { int no; char name; } book;

আগের থেকে পার্থক্য হচ্ছে আমরা এখানে নতুন একটা কীওয়ার্ড ব্যবহার করেছি, typedef। তারপর লিখছি struct। এবং আমাদের স্ট্র্যাকচারের একবারে শেষের দিকে লিখেছি আমাদের স্ট্যাকচারের নাম।
এখন আমরা আমাদের এই book স্ট্র্যাকচারের instance তৈরি করার জন্য struct কীওয়ার্ড ব্যবহার ছাড়াই তৈরি করতে পারব, যেমনঃ book myBook;
যেভাবে আমরা একটা ভ্যারিয়েবল ডিক্লেয়ার করি, ঠিক সেভাবে। আগের প্রোগ্রামটা typedef ব্যবহার করলে হয়ঃ
#include <stdio.h>

   typedef struct book{
        int no;
        char name;
        } book;

int main ()
{
    book myBook;
    myBook.no = 3;
    myBook.name = 'C';

    printf("Book No : %d\n", myBook.no);
    printf("Book Name : %c\n", myBook.name);

    return 0;
}
    
আচ্ছা, স্ট্রাকচার এর সুবিধে হচ্ছে একবার ডিফাইন করার পর ইচ্ছে মত instance তৈরি করে নিতে পারি আমরা। আগের দুইটি প্রোগ্রামে আমরা একটা স্ট্রাকচার ডিফাইন করেছি, এবং এরপর একটা মাত্র স্ট্রাকচার ডিক্লেয়ার করেছি। এখন আমরা আরেকটা প্রোগ্রাম লিখব, যেখানে একটা স্ট্রাকচারের তিনটে instance তৈরি করব।
#include <stdio.h>

   typedef struct book{
        int no;
        char name;
        } book;

int main ()
{
    book book1;
    book book2;
    book book3;

    book1.no = 1;
    book1.name = 'A';


    book2.no = 2;
    book2.name = 'B';


    book3.no = 3;
    book3.name = 'C';

    printf("Book No : %d\n", book1.no);
    printf("Book Name : %c\n \n", book1.name);

    printf("Book No : %d\n", book2.no);
    printf("Book Name : %c\n \n", book2.name);

    printf("Book No : %d\n", book3.no);
    printf("Book Name : %c\n", book3.name);

    return 0;
}
    
book এর instance তৈরি করার সময় আমরা ভিন্ন ভিন্ন লাইনে না লিখে একই লাইনে লিখতে পারি।
যেমনঃ book book1;
book book2;
book book3;

এর পরিবর্তে আমরা লিখতে পারিঃ
book book1,book2, book3;

আমরা book এর তিনটে instance তৈরি করেছি মাত্র। এবং ম্যানুয়ালি সব গুলো মেম্বারে ডেটা সেট করেছি। কিন্তু আমাদের এমন প্রোগ্রাম লিখতে হবে, যেখানে আমাদের ১০০ বা ১০০০ বা আরো বেশি instance তৈরি করতে হবে। তখন কি করব? এমন প্রোগ্রামটা দেখতে কি বিশ্রিই না দেখাবে, তাই না? কিন্তু না, আমরা এখানে কন্ডিশনাল ব্যবহার করতে পারব। লুপ দিয়ে সব গুলোতে ডেটা সেট করতে পারব। আবার লুপ দিয়ে সব গুলো থেকে ডেটা বের করে প্রিন্ট করতে পারব।
আমরা সিম্পল একটা প্রোগ্রাম লিখব এ জন্য। আসলে এ প্রোগ্রামটির জন্য স্ট্র্যাকচার ব্যবহার করতে হয় না। তারপর ও লুপ ব্যবহার করে কিভাবে স্ট্র্যাকচারের ভিন্ন ভিন্ন মেম্বার এক্সেস করতে হয়, তার একটা উদাহরণ দেখব।
প্রোগ্রামটিতে আমরা ০ থেকে ১০০ এর বর্গমুল [square root] এর একটা চার্ট তৈরি করব।
#include <stdio.h>

   typedef struct squareRoot{
        int number[100];
        double root[100];
        } squareRoot;

int main ()

{
    int i =0;
    squareRoot squareRoot1;

// setting data
    for (i =0; i<= i++){

        squareRoot1.number[i] = i;
        squareRoot1.root[i] = sqrt(i);
    }

// printing data

    for (i =0; i<= i++){
    printf("Square Root of %d ", squareRoot1.number[i]);
    printf("is : %f\n", squareRoot1.root[i]);
    }

    return 0;
}
    

এখানে sqrt() হচ্ছে একটা লাইব্রেরী ফাংশান। যার মধ্যে একটা নাম্বার দিলে ঐ নাম্বারটির বর্গমূল রিটার্ন করে। বাকি কোড গুলো তো সহজ। প্রথমে আমরা for লুপ ব্যবহার করে আমাদের squareRoot1 এর বিভিন্ন মেম্বারে ডেটা সেট করেছি। এপর আবার লুপ দিয়ে সেগুলো প্রিন্ট করেছি। এবার তো আমরা স্ট্র্যাকচার ব্যবহার করে কমপ্লেক্স কোড লিখতে পারব, তাই না? শুভ প্রোগ্রামিং…

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


ফাইল ডিক্লেয়ার

একটা ফাইল নিয়ে কাজ করার জন্য তা ডিক্লেয়ার করতে হয়। ডিক্লেয়ার করা হয় FILE পয়েন্টার দিয়ে। যেমনঃ
FILE *MyFile;
FILE বড় হাতের অক্ষরে লিখতে হয় এবং MyFile হচ্ছে পয়েন্টার ভেরিয়েবল। এটা মুলত একটা বাফার তৈরি করে কম্পিউটার মেমরি এবং ঐ ফাইল এর মধ্যে। পয়েন্টার ভেরিয়েবল তৈরি করার পর আমরা ফাইলটি ওপেন করতে পারব। তার জন্য fopen ফাংশান ব্যবহার করতে হয়। যা সাধারনত লেখা হয় এমনঃ
MyFIle = fopen(file-name, file-type);

ফাইল এর নাম এবং টাইপ দুটি স্ট্রিং। ফাইল টাইপ হচ্ছে ফাইলটা কোন মুড এ ওপেন হবে তা। যেমন Read Only, Write Only অথবা দুটিই ইত্যাদি। যেমনঃ
MyFile = fopen (“myfile.txt”,”w”);
file-type নিচের টেবিলের যে কোন একটা হতে পারেঃ


টাইপকাজ
rশুধু মাত্র ফাইলটি রিড করার জন্য ওপেন করা।
w
  • ফাইলটিতে কিছু রাইট করার জন্য ওপেন করা।
  • ফাইলে যদি আগে কিছু থাকে তাহলে তা মুছে যাবে।
  • ফাইল যদি না থাকে, তাহলে অটোমেটিক ভাবে তৈরি হবে।
a
  • ফাইলের শেষে কিছু রাইট করার জন্য ওপেন করা।
  • যদি ফাইলে আগে কিছু থাকে, তাহলে তার শেষে রাইট হবে।
  • ফাইল যদি না থাকে, তাহলে অটোমেটিক ভাবে তৈরি হবে।
r+ফাইলটি রিড করা বা রাইট করার জন্য ওপেন করা। এবং ফাইলের শুরুতে কিছু লেখা।
w+ফাইলটি রিড করা বা রাইট করার জন্য ওপেন করা।
a+ফাইলটি রিড করা বা রাইট করার জন্য ওপেন করা। এবং ফাইলের শেষে কিছু লেখা।

ফাইলে ডেটা লেখাঃ

ফাইল ওপেন করে তাতে কিছু লেখার জন্য fputs ফাংশান ব্যবহার করা হয়। লিখতে হয় এভাবেঃ

fputs (“Writing to a file using fopen.”,MyFile);
ফাইলটি রিড বা রাইট করা হলে ফাইলোটি বন্ধ বা ক্লোজ করতে হয়, তার জন্য ব্যবহার করা হয় fclose ফাংশনঃ

fclose (MyFile);

সম্পূর্ণ একটা প্রোগ্রামঃ
#include <stdio.h>
int main ()
{
    FILE * MyFile;
    char string[10];
    MyFile = fopen ("myfile.txt","a");

    fputs ("Writing to a file using fopen. \n",MyFile);
    fclose(MyFile);

    return 0;
}
    
এখানে শুধু মাত্র ফাইল টাপটা পরিবর্তন করেছি। এখন যতবার তুমি প্রোগ্রাম রান করবে, myfile.txt ফাইলে ততবার একটি করে লেখা যুক্ত হতে থাকবে।

উপরের উদাহরণে ফাইলটি আমাদের প্রোগ্রাম যে ফোল্ডারে, সেখানেই সেভ হবে। তুমি চাইলে অন্য যে কোন পাথ বলে দিতে পারো। যেমন নিচের প্রোগ্রামটি দেখোঃ
#include <stdio.h>
int main ()
{
 FILE * MyFile;
 MyFile = fopen ("F:\myfile.txt","a");
 if (MyFile!=NULL)
 {
     fputs ("Writing to a file using 'fopen' example.",MyFile);
     fclose (MyFile);
 }
 return 0;
}

    

তোমার কম্পিউটারে যদি F ড্রাইভ থাকে, তাহলে myfile.txt ফাইলটা F ড্রাইভে সেভ হবে। তুমি চাইলে অন্য যে কোন ড্রাইভ বলে দিতে পারো। বলে দিতে পারো ফোল্ডারও। যদি তোমার ফোল্ডার হয় F:\My Folder তাহলে তোমাকে লিখতে হবে এভাবেঃ F:\\My Folder\\myfile.txt। কারণ সি প্রোগ্রামিং এ ব্যাকস্ল্যাস (\) ব্যবহার করার জন্য ডাবল ব্যাকস্ল্যাস ব্যবহার করতে হয়।


ফাইল থেকে ডেটা পড়াঃ

ফাইল থেকে ডেটা পড়ার জন্য fscanf ব্যবহার করা হয়।
নিচের প্রোগ্রামটি রান করে দেখো। প্রোগ্রামটি রান করার পূর্বে খেয়াল রাখতে হবে যেন তোমার প্রোগ্রামটি যে ফোল্ডারে রয়েছে, ঐ ফোল্ডারে myfile.txt নামে একটা ফাই ল থাকে। এবং ঐ ফাইলে কিছু লেখা থাকে। না হয় প্রোগ্রামটি ভুল দেখাবে।
#include <stdio.h>
int main ()
{
    FILE * MyFile;
    char string[1000];
    MyFile = fopen ("myfile.txt","r+");

    while(! feof(MyFile))
    {
        fscanf(MyFile,"%s",string);

        printf("%s ", &string);
    }
    fclose (MyFile);
    return 0;
}
    
প্রোগ্রামটি রান করলে myfile.txt ফাইল থেকে লেখা গুলো পড়বে এবং কনসোলে দেখাবে। প্রোগ্রামটি কিভাবে কাজ করেছে, তা জানা যাক।

feof দিয়ে end-of-file চেক করা হয়। অর্থাৎ যতক্ষন পর্যন্ত ফাইলের মধ্যে কোন ডেটা থাকবে ততক্ষন পর্যন্ত ফাইলটির ডেটা গুলো fscanf দিয়ে রিড করবে।
fscanf এর তিনটা প্যারামিটার রয়েছে। fscanf(file-name, data-type, variable);
file-name হচ্ছে ফাইলের নাম। যে ফাইল থেকে ডেটা পড়া হবে। data-type হচ্ছে ফাইলের ডেটা টাইপ। বা কোন টাইপে ডেটা গুলো পড়া হবে। এখানে char টাইফের ডেটা পড়া হয়েছে। ইচ্ছে করলে int অথবা floating point ডেটা পড়া যাবে। তবে তখন খেয়াল রাখতে হবে যেন ফাইলে ইন্টিজার বা ফ্লোটিং পয়েন্ট ডেটা থাকে। variable হচ্ছে ভেরিয়েবলের নাম, যেখানে ডেটা গুলো ফাইল থেকে পড়ে সংরক্ষিত থাকবে।
আমরা এ পর্যন্ত যে ফোল্ডারে আমাদের সি প্রোগ্রাম টা রয়েছে তা থাকে ফাইলটি ওপেন করছি বা রিড করছি। ইচ্ছে করলে আমরা যে কোন ডিরেক্টরি থেকে ফাইলটি ওপেন করতে পারি। file-name এর জায়গায় পুরো ফাইল পাথ দিলেই হবে। নিচের উদাহরনটি দেখোঃ
#include <stdio.h>

int main ()
{
    FILE * MyFile;
    char string[1000];
    MyFile = fopen ("F:\\myfile.txt","r+");

    while(! feof(MyFile))
    {
        fscanf(MyFile,"%s",string);
        printf("%s ", &string);
    }
    fclose (MyFile);
    return 0;
}
    
এটা ছিল ফাইল অপারেশন নিয়ে ব্যাসিক ধারণা। এবার তুমি তোমার ইচ্ছে মত ফাইল নিয়ে কাজ করতে পারো। ফাইলে যে কোন ডেটা টাইপের ডেটা রাখো। এরপর তা পড়। লুপ ব্যবহার কর। স্ট্রিং ব্যবহার কর।


অনুশীলনঃ

  1. সি প্রোগ্রামিং এ কোন ফাইলে কিছু লেখার জন্য কোন ফাংশন ব্যবহার করা হয়?
  2. কোন ফাইল থেকে ডেটা পড়ার জন্য কোন ফাইল টাইপ ব্যবহার করা হয়?
  3. কোন ফাইলে ডেটা লেখার জন্য কোন ফাইল টাইপ ব্যবহার করা হয়?
  4. কোন ফাইল থেকে ডেটা পড়ার জন্য কোন ফাংশন ব্যবহার করা হয়?
  5. fclose কেন ব্যবহার করা হয়?
  6. fopen এর কাজ কি? কেন ব্যবহার করা হয়?
  7. fputs ব্যবহার করে একটা প্রোগ্রাম লিখ।
  8. একটা প্রোগ্রাম লিখ, যা তোমার নাম, তোমার স্কুল/কলেজ/ইউনিভার্সিটি এবং তোমার রোল বা আইডি আলাদা আলাদা লাইনে একটা ফাইলে লিখে রাখবে।
  9. একটা প্রোগ্রাম লিখ, যা দিয়ে একটা ফাইল থেকে ইন্টিজার ভ্যালু গুলো পড়তে পারবে।

c - strings/ ষ্ট্রিং ঃ
স্ট্রিং হচ্ছে কারেকটার সেট। একটা ওয়ার্ড, একটা বাক্য, একটা প্র্যারাগ্রাফ, সব গুলোই স্ট্রিং। যেমন Hello World একটা স্ট্রিং। আবার hello ও একটা স্ট্রিং। world ও একটা স্ট্রিং। যখন শুধু একটা বর্ণ, তখন তা কারেকটার।
আগে বলেছি স্ট্রিং হচ্ছে কারেকটার সেট। হ্যা, একটা one-dimensional কারেকটার অ্যারে হচ্ছে স্ট্রিং। লেখাটি পড়ার আগে অ্যারে/Array সম্পর্কে ধারণা থাকা লাগবে। একটা স্ট্রিং নিচের মত করে ডিক্লেয়ার করা হয়ঃ
char string[50] = “This is a static string”;
আর প্রিন্ট করার জন্য লিখতে হয়ঃ
printf(“%sn”, string);
আমরা একটা স্ট্রিং ডিক্লেয়ার এবং তা প্রিন্ট করার জন্য একটা প্রোগ্রাম লিখে ফেলিঃ
#include <stdio.h>
#include <string.h>
int main ()
{
    char string[50] = "Hello";
    printf("%s\n", string);

    return 0;
}
    
Hello এ স্ট্রিংটা প্রিন্ট করার জন্য আমরা 50 সাইজের একটা কারেকটার অ্যারে ডিক্লেয়ার করেছি, কিন্তু আমাদের বর্ণ মাত্র ৫টা। তাই আমাদের এত বড় অ্যারে ডিক্লেয়ার করার দরকার নেই। তার জন্য আমরা 5 সাইজের একটা অ্যারে ডিক্লেয়ার করলেই হবে। এখানে বলে রাখা ভালো যে, আমরা যখন একটা স্ট্রিং ডিক্লেয়ার করব, তখন সব গুলো বর্ণের শেষে অটোমেটিক্যালি একটা null character ” যুক্ত হবে। নিচের ছবিটা দেখি।
string_representationHello স্ট্রিং এর জন্য আমাদের টোটাল তাহলে ৬ সাইজের একটা অ্যারে দরকার। Hello এর পাঁচটা বর্ণ এবং একটা নাল কারেকটার। আবার আমরা জানি অ্যারে এর indexing শুরু হয় ০ থেকে। তাহলে আমাদের Hello স্ট্রিং নিচের মত করেও ডিক্লেয়ার করতে পারিঃ
char string[5] = “Hello”;
আবার আমরা চাইলে কত সাইজের অ্যারে ব্যবহার করব তা রান টাইমের উপর ছেড়ে দিতে পারি। প্রোগ্রাম অটোম্যাটিক্যালি একটা সাইজ এসাইন করে দিবে। তার জন্য লিখবঃ
char string[] = “Hello”;
এবার একটা প্রোগ্রাম লিখি, যেখানে ইউজার থেকে একটা ব্যাক্য ইনপুট নিবে, এবং পরে তা প্রিন্ট করবেঃ
#include <stdio.h>
#include <string.h>

int main ()
{
    char string[100];
    printf("Enter a sentance: ");

    scanf(" %[^\n]s", &string);
    printf("%s\n", string);

    return 0;
}
    
উপরের প্রোগ্রামে আমরা scanf এর ভেতর লিখছি %[^n]s। scanf দিয়ে স্পেস ইনপুট নেওয়া যায় না। তার জন্য স্পেশাল মডিফায়ার ব্যবহার করতে হয়। সে জন্য এভাবে লেখা। আর scanf ছাড়া আমরা gets দিয়ে স্ট্রিং ইনপুট নিতে পারি। gets দিয়ে উপরের প্রোগ্রাম লিখলে হবেঃ
#include <stdio.h>
#include <tring.h>

int main ()
{
    char string[100];
    printf("Enter a sentance: ");

    gets(string);
    printf("%s\n", string);

    return 0;
}
    
সিম্পল, তাই না?


Strings Concatenation

Concatenation মানে হচ্ছে জোড়া দেওয়া। দুইটা আলাদা আলাদা স্ট্রিং এক সাথ করার জন্য Strings Concatenation ব্যবহার করা হয়। এর জন্য একটা লাইব্রেরী ফাংশান রয়েছে। strcat(), যা ব্যবহার করে দুইটা স্ট্রিং এক সাথ করা যায়। strcat() ইনপুট হিসেবে দুইটা স্ট্রিং নেয়। এভাবেঃ strcat(string1, string2) এরপর string2 এর ভেতরে থাকা স্ট্রিং string1 এর সাথে যুক্ত করে দেয়, নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>
#include <string.h>
int main ()
{
    char string1[] =  "Hello ";
    char string2[] = "World";
    strcat(string1, string2);

    printf("%s\n", string1);

    return 0;
}
    

strcmp()

দুইটা স্ট্রিং কম্পেয়ার করার জন্য ব্যবহার করা হয় strcmp(string1, string2)। দুইটা স্ট্রিং এ ফাংশনে পাস করলে তিনটা মান রিটার্ন করেঃ
  • রিটার্ন ভ্যালু ০ থেকে ছোট হবে যদি string1 থেকে string2 বড় হয়।
  • রিটার্ন ভ্যালু ০ থেকে বড় হবে যদি string1 থেকে string2 ছোট হয়।
  • রিটার্ন ভ্যালু ০ হবে, যদি দুইটা স্ট্রিং একই হয়।
#include <stdio.h>
#include <string.h>
int main(){

    int ret;
    char string1[50], string2[50];
    printf("Enter string 1:");
    gets(string1);

    printf("Enter string 2:");
    gets(string2);

    ret = strcmp(string1, string2);

    if(ret < 0){
          printf("string1 is less than string2");
       }
   else if(ret > 0){
          printf("string2 is less than string1");
       }
   else{
          printf("string1 is equal to string2");
       }



   return 0;
}
    

strcpy()

strcpy() তে দুইটা স্ট্রিং পাস করলে দ্বিতীয় স্ট্রিং এর ভ্যালু প্রথম স্ট্রিং এ কপি করবে। যেমন strcpy(string1, string2) পাস করলে string2 এর ভেতরের স্ট্রিংটা string1 এ এসাইন হয়ে যাবে। নিচের প্রোগ্রামটি দেখিঃ
#include <stdio.h>
#include <string.h>
int main ()
{
    char string1[] =  "Hello ";
    char string2[] = "World";
    strcpy(string1, string2);

    printf("%s\n", string1);
    printf("%s\n", string2);

    return 0;
}
    
এবার আমরা একটা প্রোগ্রাম লিখব, যেখানে একটা বাক্য থেকে কোন একটা বর্ণ কতবার আছে, তা বের করতে পারব। ইনপুট হিসেবে একটা বাক্য নিবে। তারপর নিবে কোন বর্ণটার সংখ্যা বের করতে হবে, তা। এবং পরে ঐ বর্ণটা কতবার রয়েছে, তা প্রিন্ট করবেঃ
#include <stdio.h>
#include <string.h>
int main(){
   char sentence[1000];
   char character;
   int i,count=0;
   printf("Enter a sentence: ");
   gets(sentence);
   printf("Enter a character to find frequency: ");
   scanf("%c",&character);

   for(i=0; sentence[i]!='\0';++i)
   {
       if(character==sentence[i])
           ++count;
   }
   printf("Frequency of %c = %d", character, count);
   return 0;
}
    
উপরের প্রোগ্রামটাতে প্রথমে ইজার থেকে একটা বাক্য ইনপুট নিচ্ছে gets দিয়ে। এরপর ইনপুট নিচ্ছে কোন কারেকটার / বর্ণটি কত বার রয়েছে, তা। এরপর for লুপ চালিয়ে আমরা বর্ণটি কাউন্ট করেছি। এরপর শেষে বর্ণটি কতবার রয়েছে, তা প্রিন্ট করেছি। for লুপে আমরা sentence[i]!=’’ ব্যবহার করেছি। এর মানে হচ্ছে for লুপটি ততক্ষণ পর্যন্ত চলবে, যতক্ষণ না নাল কারেকটারটি পায়। আর আমরা জানি প্রত্যেকটা স্ট্রিং অ্যারের শেষে একটা নাল কারেকটার থেকে।

আরো প্রয়োজনীয় টিপস পেতে সাথেই থাকুন...

Comments

Popular Post

আসুন খুব সহজে HTML শিখে ফেলি

HTML কি? HTML  একটা কম্পিউটার ল্যাঙ্গুয়েজ, যা পৃথিবীর বিশাল তথ্য-ভান্ডারকে ইন্টারনেটের মাধ্যমে প্রদর্শনের সুযোগ তৈরি করে দিয়েছে। একটা ওয়েব পেজের মূল গঠন তৈরি হয়  HTML  দিয়ে। HTML  কোন প্রোগ্রামিং ল্যাঙ্গুয়েজ নয়, একে  Hyper Text Mark Up Language  বলা হয়।  Mark Up Language  এক সেট  Mark Up  ট্যাগের সমন্বয়ে গঠিত হয়। একটা ওয়েব পেজের বিভিন্ন অংশ ব্রাউজারের মাধ্যমে কিভাবে প্রদর্শিত হবে, তা  HTML এ  Mark Up  ট্যাগ সমূহ ব্যবহার করে প্রকাশ করা হয় । HTML এর ইতিহাস HTML  বা  Hyper Text Mark Up Language তৈরি করেছেন টিম বার্নাস-লী।  HTML  তৈরির উদ্দেশ্য ছিল বৈজ্ঞানিক গবেষণার তথ্য উপাত্ত দ্রুত পৃথিবীর বিভ্ন্নি স্থানে আদান প্রদানের ব্যবস্থা করা। ১৯৯০ সালের দিকে  NCSA  কর্তৃক ডেভলপকৃত মোজাইক ব্রাউজারের মাধ্যমে HTML পরিচিতি লাভ করে। ১৯৯৭ এর জানুয়ারীতে  WC3  কর্তৃক প্রথম ডেভলপকৃত  HTML3.2  প্রকাশিত হয়। একই বছরে শেষে ডিসেম্বরে  WC3 HTML  এর নত...

java টিউটোরিয়াল a টু z

জাভাস্ক্রিপ্ট কি ? (What is JavaScript ?) জাভাস্ক্রিপ্ট একটা জনপ্রিয় স্ক্রিপ্টিং ল্যাঙ্গুয়েজ, যা ওয়েব পেজের ইন্ট্রকটিভিটি ও ফাংশনালিটি বৃদ্ধি, ফরম ভেলিডেশন, ব্রাউজার নির্দেশ, সময় ও তারিখ নির্দেশ ইত্যাদি কাজে ব্যবহৃত হয়।জাভাস্ক্রিপ্ট ক্লায়েন্ট  এবং সার্ভার উভয় দিকেই কাজ করতে পারে। তাই ইহা ইউজারের নিকট থেকে ডাটা নিয়ে প্রয়োজনীয় প্রসেস সম্পন্ন করে সার্ভারে প্রেড়ণ করতে সক্ষম। জাভাস্ক্রিপ্ট  ECMA  ইন্টারন্যশনাল অর্গানাইজেশন কতৃক উদ্ভাবিত এবং তৈরি করেছিলেন ব্রান্ডন এইচ  (Brendan Eich) । জাভাস্ক্রিপ্ট এর অফিসিয়াল নাম ছিল  ECMAScript  । অনুশীলন প্রজেক্ট <html> <head> <title> www.tutohost.com</title>   <style> body{background: #FFC} </style>  <script type="text/javascript"> </script>   </head> <body> <form> <input type ="button" value = "Click Me" onClick="alert('Welecome to www.tutorialbd.com')"> </form> </body>  </html> একট...