Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Saturday, June 28, 2014

ভিজ্যুয়াল প্রোগ্রামিং

Visual শব্দটির অর্থ চাক্ষুষ বা সরাসরি দৃশ্যমান। Programming এর ভাষায় Visual মানে কোড না লিখে প্রোগ্রামের বিভিন্ন User Interface সমূহ প্রোগ্রামে সংযুক্ত করা। এক্ষেত্রে User Interface সমূহে সংযোজনের কাজ অনেকটা চিত্র আঁকার মতই। সুতরাং ভিজ্যুয়াল প্রোগ্রামিং একটি চিত্রভিত্তিক প্রোগ্রামিং মডেল যা Windows Operating System কর্তৃক সমর্থিত। মেনুচালিত প্রোগ্রাম রচনার ক্ষেত্রে এ মডেলটি খুবই উপযোগী।
মূলত ভিজ্যুয়াল প্রোগ্রামিং হচ্ছে এমন এক ধরনের উইন্ডোজ ভিত্তি Object Oriented Programming যাতে মেনু, চিত্র, বিভিন্ন ধরনের টুল বা কন্ট্রোল ব্যবহার করে বাস্তব ভিত্তিক যে কোন সমস্যা অতি সহজে সমাধান করা যায়।

বহুল প্রচলিত ভিজ্যুয়াল সফটওয়্যার সমূহঃ


  • ভিজ্যুয়াল বেসিক
  • ভিজ্যুয়াল ফক্সপ্রো
  • ভিজ্যুয়াল সি
  • ভিজ্যুয়াল সি++
  • ভিজ্যুয়াল জাভা
  • পাওয়ার বিল্ডার
  • ডেভেলপার ২০০০ ইত্যাদি।

ভিজ্যুয়াল প্রোগ্রামিং এর বৈশিষ্ট্যসমূহ


  • ভিজ্যুয়াল প্রোগ্রামিং এর ক্ষেত্রে ভিজ্যুয়াল ডেভেলপমেন্ট এনভায়রনমেন্ট ব্যবহার করে নতুন কোন এপ্লিকেশন ডেভেলপ করার পুরো প্রক্রিয়াটিই ভিজ্যুয়াল এবং গ্রাফিক্স প্রকৃতির।
  • ভিজ্যুয়াল প্রোগ্রামিং এর বেলায় GUI (Graphical User Interface) অপারেটিং সিস্টেম যেমন উইন্ডোজ ব্যবহৃত হয়।
  • Command এর পরিবর্তে Menu, Tools বা Control ব্যবহার করে সমস্যার সমাধান করা যায়। User গণ Command মুখস্থ না করে মাউসের মাধ্যমে ক্লিক করে যে কোন কার্য সম্পন্ন করতে পারে।
  • প্রয়োজনীয় যথেষ্ট সংখ্যক লাইব্রেরি ফাংশন, সাবরুটিন, কাস্টম লাইব্রেরি ও কাস্টম অবজেক্ট তৈরির সুবিধা বিদ্যমান থাকায় স্বল্প সময়ে প্রোগ্রাম রচনা করা যায়।
  • এডিটিং এর বেলায় কোড এর পরিবর্তে শক্তিশালী কন্ট্রোল ব্যবহার করে মাউস ক্লিক এর মাধ্যমে নিজের ইচ্ছামত ডিজাইন করে ফলাফল পাওয়া যায়।
  • ভিজ্যুয়াল প্রোগ্রামিং এর অসাধারণ ডিবাগিং পদ্ধতি বিদ্যমান। ফলে সহজে ও অল্প সময়ে প্রোগ্রামের ভুল-ত্রুটি সনাক্তকরণ ও সংশোধন করা যায়।
  • সর্বোপরি ভিজ্যুয়াল প্রোগ্রামিং এ ব্যবহৃত অবজেক্টসমূহ বাস্তব জীবনের সাথে সম্পর্কিত বিধায় এটি ইউজার ফ্রেন্ডলি।

ভিজ্যুয়াল প্রোগ্রামিং এর ব্যবহারিক ক্ষেত্রসমূহ


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

ভিজ্যুয়াল প্রোগ্রামিং এর প্রয়োজনীয়তা


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

সবাইকে অসংখ্য ধন্যাবাদ ।।।। ভালো থাকবেন ।।।।
……… {সমাপ্ত}………

স্ট্যান্ডার্ড টেম্প্লেট লাইব্রেরী

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


দ্বিতীয় অংশ – স্ট্যান্ডার্ড টেম্প্লেট লাইব্রেরী

STL হল একটা বেশ বড়সড় একটা লাইব্রেরী। মোটামুটি বেশিরভাগ ডাটা স্ট্রাকচার আর হাবিজাবি এটার মধ্যে লিখে রাখা আছে, তোমাকে শুধু জানতে হবে সেটা তুমি কিভাবে ব্যবহার করবে।
 

 ভেক্টর

মাঝে মাঝে এমন হয় – আমাদের একটা 2D অ্যারে দরকার, যেটায় মোটামুটি প্রতিটায় সর্বোচ্চ ১০০০০ টা ডাটা রাখতে হবে, আর প্রতিটা ডাটায় সর্বোচ্চ ১০০০০টা করে ডাটা রাখা লাগবে। কিন্তু আমাকে এটাও বলা আছে যে সর্বোচ্চ ১০০০০০ টা ডাটা থাকতে পারে। 

খুব সাধারণভাবে যেটা মাথায় আসে, সেটা হচ্ছে এরকম কিছু একটা 
 int array[10000][10000];

তাই না? এটা কিন্তু বেশ বড়সড় একটা অ্যারে। আমার কম্পিউটার মাথা ঘুরে পড়ে যাবে তাকে এই পরিমান মেমরি অ্যালোকেট করতে বললে, কিন্তু আমার আসলে এত বেশি জায়গা লাগছে না, কারণ আমাকে বলেই দেয়া হয়েয়ে ডাটা সবমিলে সর্বোচ্চ ১০০০০০ টা থাকে পারে। 

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

ভেক্টর হলো একটা অ্যারে, যেটায় ডাইনামিকালি জিনিসপাতি ঢুকিয়ে রাখা যায়। মানে, এটাও একটা অ্যারে, কিন্তু সেটা ঠিক ততটুকু মেমরি খায়, যতটুকু খাওয়া লাগে।

ভেক্টর ডিক্লেয়ার করে এভাবে

vector< int > array;

তুমি যদি অন্য কোন টাইপের ডাটা নিতে চাও তাইলে int এর জায়গায় সেই ডাটার নাম লিখতে হবে। যেমন এটা আরো কিছু অ্যারে। 

vector< double > water;
vector< long long > balance;
vector< char > characters;
vector< day > diary;

ভেক্টরে কোন ডাটা রাখতে হলে, সেই ভেক্টরের শেষে ডাটাটাকে পুশ করতে হয়।

array.push_back( 100 );


 আর ভেক্টরে কটা ডাটা আছে সেটা আমরা জানতে পারি .size() ফাংশনকে কল করে। যেমন ধরো, আমি একটা ভেক্টরে কিছু ইন্টেজার ঢুকাবো, তারপর সবাইকে প্রিন্ট করবো, সেটার কোড হবে এরকম।


int main() {
    vector< int > v;
    v.push_back( 1 ); 
    v.push_back( 2 ); 
    v.push_back( 3 ); 
    v.push_back( 4 );     for(int i=0; i<v.size(); i++) cout << v[i] << endl;
    
    return 0;   
}

বাকি সব কিছুতে ভেক্টরকে সাধারণ অ্যারের মত ব্যবহার করা যায়। যেমন আমি 0th এলিমেন্টটা পাল্টে দিতে পারি v[0] = 10000 লিখে। আরেকটা মজা হচ্ছে আমরা অ্যারেতে ধাম করে সরাসরি কপি করতে পারি না । কিন্তু ভেক্টরে সেটা করা যায়। 
 

int main() {    vector< int > v, t;    v.push_back( 1 );    v.push_back( 2 );    v.push_back( 3 );    v.push_back( 4 );    t = v; // copying    for(int i=0; i<t.size(); i++) cout << t[i] << endl;
    return 0;

ভেক্টরে যদি আমি 2D ডাটা রাখতে চাই তাহলে সেটা দুভাবে করা যায়। আমি প্রথমটা প্রেফার করি, পরেরটা দেখতে আমার ভয় ভয় লাগে। কিন্তু মাঝে মাঝে কোন পথ থাকে না সেটা লেখা ছাড়া।

vector< int > v[100];
vector< vector< int > > v;
vector< vector< vector< int > > > v; // 3 dimensional

একটা জিনিসে একটা সাবধান থেকো, vector<vector<int>> v; এভাবে লিখলে >> এর জন্য কিছু কম্পাইলর কিন্তু এরর মারে।


স্ট্রিং

স্ট্রিং হচ্ছে মজার একটা ডাটা স্ট্রাকচার। মোটামুটি এর কাজ অনেকটা ক্যারেক্টার অ্যারের মতই। কিন্তু এটা ব্যবহার করা বেশ সহজ। যেমন নিচে কিছু স্ট্রিং টাইপের জিনিসপাতির কাজ দেখিয়ে দিলাম।


int main() {    string a, b, c;    a = “this is a string”; // easy assigning    b = a; // copy hoye gelo! :O    c = a + b // c te rakhlam a ar b er concatation    cout << c << endl; // print korlam    printf(“%s\n”, c.c_str() ); // printf diyei korlam na hoy
    cout << c.size() << endl; // length print korlam    for(int i=0; i<c.size(); i++) cout << c[i] ; 
// ekta ekta kore character print korlam
return 0;
}

তুমি যদি এখন স্ট্রিং এর ভেক্টর রাখতে চাও তাহলে সেটাকে ডিক্লেয়ার করতে হবে এভাবে।

vector< string > vs;

সহজ না?

স্ট্যাক

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

এই জিনিসটাকে বলে স্ট্যাক। মানে আমরা সবার পরে যাকে প্রসেসিং করতে ঢুকাচ্ছি তাকে যদি আগে প্রসেসিং করি তাহলে সেটাই স্ট্যাক। STL এ স্ট্যাক ব্যবহার করতে হয় এভাবে।

 stack< int > st;
st.push( 100 ); // inserting 100
st.push( 101 ); // inserting 101
st.push( 102 ); // inserting 102

while( !st.empty() ) {
cout << st.top() << endl; // printing the top
st.pop(); // removing that one
}

কিউ

ধরো তুমি বাসের টিকেট কিনে লাইনে দাঁড়িয়ে আছো। এখন বাসে ওঠাটা হচ্ছে আমার কাজ(প্রসেসিং)। কাকে আগে বাসে উঠতে দিবে? যে সবার আগে এসেছে, তাকে। এটাকে বলে কিউ – যে সবার আগে এসেছে তাকে আগে প্রসেস করা। 
 


queue< int > q;
q.push( 100 ); // inserting 100
q.push( 101 ); // inserting 101
q.push( 102 ); // inserting 102

while( !q.empty() ) {
cout << q.front() << endl; // printing the front
q.pop(); // removing that one
}
 

প্রায়োরিটি কিউ

আমাদের পাড়ার মুচির প্রতিদিন একগাদা কাজ আসে। সে করে কি, সবচে’ বেশি পয়সা পাওয়া যাবে যেই কাজে সেই কাজগুলো সবার আগে করে ফেলে। সে প্রায়োরিটি তাদেরকেই বেশি দেয় যাদের কাজে বেশি পয়সা পাওয়া যাবে। 

এটাও এক ধরণের কিউ শুধু পার্থক্য হচ্ছে যার দাম যত বেশি তাকে তত আগে প্রসেস করা হচ্ছে।

priority_queue< int > q;
q.push( 10230 ); // inserting 10230
q.push( 1021 ); // inserting 1021
q.push( 102322 ); // inserting 102322

while( !q.empty() ) {
cout << q.top() << endl; // printing the top
q.pop(); // removing that one
}


ইটারেটর

ইটারেটার হলো  অনেকটা সি এর পয়েন্টারের মত একটা জিনিস। ইটারেটর আসলে পরে কাজে লাগবে, কারণ অনেক জায়গায়ই STL এর ফাংশনগুলো একটা অ্যাডরেস পাঠায়, যে আমি যেই ডাটাটাকে খুঁজছি, সেটা ঠিক কোথায় আছে।

ইটারেটর ডিক্লেয়ার করে এইভাবে

vector< int > :: iterator i;
vector< double > :: iterator j;


আর ফর লুপ দিয়ে একটা ভেক্টরের প্রথম থেকে শেষ পর্যন্ত সব এলিমেন্টের গলা কাটতে চাই তাহলে সেটা লিখতে হবে এভাবে।

vector< int > v; v.pb( 1 ); v.pb( 2 ); v.pb( 3 );
vector< int > :: iterator i;
for( i = v.begin(); i < v.end(); i++ ) {
printf(“%d\n”, *i);
// ei khane gola kato!
}

 
সর্ট

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

STL এ সর্ট করা খুব সহজ। ধরো আমার একটা ভেক্টর v আছে, সেটা আমি সর্ট করবো। তাহলো আমার শুধু লিখতে হবে -

sort( v.begin(), v.end() );
তাহলে সে ছোট থেকে বড় তে ভেক্টরটাকে সর্ট করে ফেলবে। এখন ধরো আমাকে যদি আরেকটু ঝামেলার কিছু করতে বলে। যেমন ধরো চাচা চৌধুরী তার মেয়ের বিয়ে দিবে, তো সে গেলো ঘটক পাখি ভাইয়ের কাছে। ঘটক পাখি ভাইয়ের কাছে একটা ছেলে মানে, তার নাম-ধাম, তার বংশ, সে কত টাকা কামায়, তার উচ্চতা কতো, আর তার ওজন কত। ছেলেটা সি++ এ কোড করে না জাভাতে কোড করে, সেটা নিয়ে ঘটক পাখি ভাইয়ের কোনই মাথা ব্যাথা নাই। তো সে করলো কি চাচা চৌধুরীকে শুধু এই ক্য়টা ডাটাই সাপ্লাই দিলো কয়েকটা বস্তা ভরে। এখন চাচা চৌধুরী পাড়ার প্যান্ট ঢিলা মাস্তানের কাছ থেকে শুনলো তুমি একটা বস প্রোগ্রামার, তো সে এসে তোমাকে বলল, “বাবাজি! আমাকে একটা সফটওয়্যার বানিয়ে দাও, যেটা আমার ডাটাগুলোকে সাজাবে”।

বেশ তো, এখন আমার ডাটাটা হচ্ছে এরকম – (চাচা চৌধুরী আবার বংশ নিয়ে মাথা ঘামায় না)

struct data {
    char name[100];
    int height, weight;
    long long income;
};

চাচা চৌধুরী যেটা নিয়ে মাথা ঘামায় সেটা হলো পোলার কত টাকা কামাই। যদি দুইটা পোলার সমান কামাই হয়, তাইলে যেই পোলার হাইট ভালো, সেই পোলা লিস্টে আগে থাকবে। আর যদি দুই পোলার হাইট সমান হয় তাইলে যেই পোলার ওজন কম, সেই পোলা আগে থাকবে। আর যদি দুই পোলার ওজন সমান হয়, তাইলে যেই পোলার নাম ছোট সেই পোলা আগে থাকবে।

এখন তোমাকে এই অনুযায়ী সর্ট করে দিতে হবে। আর তুমি যদি বেশি হাংকি পাংকি করো, তাইলে প্যান্ট ঢিলা মাস্তান এসে তোমাকে সাইজ করে দিবে।

এই কাজটা দুই ভাবে করা যায়। সবচে সহজটা হলো একটা কম্পেয়ার ফাংশন লিখে।

bool compare( data a, data b ) {
    if( a.income == b.income ) {
        if( a.height == b.height ) {
            if( a.weight == b.weight ) 
              return strlen( a.name ) < strlen( b.name );
else return a.weight < b.weight;
}else return a.height > b.height;
}else return a.income > b.income;
}


এই ফাংশনটা গ্লোবালি ডিক্লেয়ার করে যেখানে তুমি সর্ট করতে চাও সেখানে লিখতে হবে।
sort( v.begin(), v.end(), compare );

কম্পেয়ার ফাংশনটা রিটার্ন করবে a কি b এর আগে বসবে কি না। আর কিছু না।

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

আমি যদি একই কাজটা অপারেটর ওভারলোড দিয়ে করতে চাই, সেটা এরকম হবে।

struct data {
char name[100];
int height, weight;
long long income;

bool operator < ( const data& b ) const {
if( income == b.income ) {
if( height == b.height ) {
if( weight == b.weight )
                   return strlen( name ) < strlen( b.name );
                else return weight < b.weight;
            }else return height > b.height;
        }else return income > b.income;
    }};

এখানে কিন্তু আমি এই ডাটাটাকেই অন্য আরেকটা ডাটা b এর সাথে তুলনা করছি, সেজন্য আমার আগেরটার মতো a কে লাগছে না।

আর আমার সর্ট এর কমান্ড লিখতে হচ্ছে এইভাবে।
     sort( v.begin(), v.end() );

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

data array[100];
sort( array, array + n );

যেখানে n হচ্ছে অ্যারেতে কতগুলো ডাটাকে তুমি সর্ট করতে চাও।

তুমি যদি 3 নাম্বার (0 based)থেকে 10 নাম্বার পর্যন্ত সর্ট করতে চাও লিখো
 sort( array+3, array+11 );

 

সেট 

কোন কিছুর সেট বলতে আসলে বুঝায় শুধু জিনিসগুলোর নাম একবার করে থাকাকে। 
যেমন A = { রহিম, করিম, গরু, বিড়াল, করিম, বালিশ, রহিম, করিম } একটা সেট না, কিন্তু
 A = { রহিম, করিম, গরু, বিড়াল, বালিশ } একটা সেট।

STL এর সেট করে কি, সেট এ সব ডাটা গুলো একবার করে রাখে, আর ডাটাগুলোকে সর্ট ও করে রাখে। এটা হলো সেট এর কাজ কারবার - 


    set< int > s;
s.insert( 10 ); s.insert( 5 ); s.insert( 9 );

set< int > :: iterator it;
for(it = s.begin(); it != s.end(); it++) {
cout << *it << endl;
}
যদি তুমি স্ট্রাকচার টাইপের ডাটা রাখতে চাও সেট এ, শুধু < অপারেটরটা ওভারলোড করে ওকে বলে নিও, যে তুমি ছোট বলতে কি বুঝাচ্ছো।  বাকি কাজ ওই করবে। 

সেট সাধারণত এধরণের প্রবলেমগুলোতে কাজে লাগে। আমাকে অনেকগুলো সংখ্যা দিয়ে বলল, এখানে ইউনিক কয়টা সংখ্যা আছে। সেক্ষেত্রে আমি খালি একটার পর একটা সংখ্যা ইনপুট নিতে থাকবো তো নিতেই থাকবো, আর সেটে ঢুকাবো তো ঢুকাতেই থাকবো, তারপর খালি সেটের সাইজ প্রিন্ট করে দিবো। কেল্লা ফতেহ!

ম্যাপ

ম্যাপও সেটের মতো একটা জিনিস। কিন্তু ম্যাপ সেটের মত কোন জিনিস একটা রেখে ওই ধরণের বাকি সবাইকে বাইরে ফেলে দেয় না। 

তবে এভাবে ভাবার চেয়ে ম্যাপকে আরেকটু সহজভাবে ভাবা যায়। একটা অ্যারের কথা চিন্তা করো, আমরা করি কি অ্যারের একটা ইনডেক্সে ডাটা জমাই না? কেমন হতো, যদি ইনডেক্সটা শুধু সংখ্যা না হয়ে যেকোন কিছু হতে পারতো? ধরো, ১ নম্বর ইনডেক্সে না রেখে, “বাংলাদেশ” নামের ইনডেক্সে ডাটা যদি রাখতে পারতাম? তখন ব্যাপারটা দাঁড়াতো আমাদের একটা ম্যাজিক অ্যারে আছে যেটাই আমরা যেকোন ধরণের ডাটা জমিয়ে রাখতে পারি আমাদের ইচ্ছা মতো যে কোন ধরণের ইনডেক্স দিয়ে।

সহজভাবে ম্যাপকে তুমি এভাবে চিন্তা করতে পারো, ম্যাপ হচ্ছে একটা অ্যারে, যেটার ইনডেক্স যেকোন কিছুই হতে পারে, আর সেটাতে যেটা ইচ্ছে সেটাই রাখা যেতে পারে!

map< string, int  > m;
string goru;

while( cin >> goru ) {
if( goru == “moro” ) break;
m[ goru ] ++;
cout << goru <<” ase ” << m[ goru ] << ” ta :D ” << endl;
}
এই প্রোগ্রামটা করবে কি, গরুর নাম ইনপুট নিতে থাকবে, আর প্রতিবার বলবে যে ওই জাতের কয়টা গরু আছে।  ম্যাপকে অ্যারের মত ধরেই ইনক্রিমেন্ট করা যায়।

অবশ্য তুমি যদি তোমার বানানো কোন স্ট্রাকচার/ক্লাস রাখতে চাও ইনডেক্স হিসেবে, তোমাকে সেটার জন্য < অপারেটরটা ওভারলোড করে দিতে হবে।

 স্ট্রিংস্ট্রিম

 ধরো কোন শয়তান খুব শখ করে প্রবলেম সেট তৈরী করলো, আমাকে বলল, “তোমাকে একলাইনে যত্তগুলা ইচ্ছা তত্তগুলা করে সংখ্যা দিমু, তুমি আমারে সর্ট কইরা দিবা! মুহাহাহাহা!” তখন কষে একটা চড় মারতে ইচ্ছে করলেও কিছু করার নেই। তোমাকে তাই করতে হবে। 

আমরা লাইনের ইনপুট নেই হচ্ছে গেটস দিয়ে।
তো ব্যাপারটা এরকম হবে। 

char line[1000];
while( gets( line ) ) {
stringstream ss( line ); // initialize kortesi
int num; vector< int > v;
while( ss >> num ) v.push_back( num ); // :P
sort( v.begin(), v.end() );
// print routine
}


ss এর পরের হোয়াইল লুপ অংশটা তুমি cin এর মতো করেই ভাবতে পারো! ;) আমি সেভাবেই চিন্তা করি।
 

পেয়ার

STL এর একটা স্ট্রাকচার বানানো আছে, যার অবস্থা মোটামুটি এইরকম।

struct pair {
    int first, second;
};

তবে জিনিসটা এমন না, তুমি যেকোন টাইপে কাজ করতে পারো। যেমন এটা যদি আমি STL এর পেয়ার দিয়ে লিখি, জিনিসটা হবে এরকম 

pair< int, int > p; 


এই চেহারাটা কি মনে পড়ে? একে কি আগে দেখেছো? হুমম, ম্যাপের স্ট্রাকচারে আরেকবার চোখ বুলাও। ;)

আমরা ইচ্ছে মতো পেয়ার ডিফাইন করতে পারি, যেভাবে ইচ্ছে। ম্যাপের ডাটা টাইপের মতনই!

pair< int, int > p;
pair< int, double > x;
pair< double, string > moru;
pair< goru, goru > fau;

যা ইচ্ছে!
 

নেক্সট পারমুটেশন, প্রিভ পারমুটেশন

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

এধরণের প্রবলেমকে বলা হয় কম্প্লিট সার্চ। আমাদের সবগুলো অপশন ট্রাই করতে হবে। ধরো তিনটা বাচ্চার জন্য অল পসিবল ট্রাই করা হচ্ছে এরকম – (জামার নাম্বার দিয়ে)

আবু গাবু ডাবু
  ১     ২    ৩
  ১     ৩    ২
  ২     ১    ৩
  ২     ৩    ১
  ৩     ১    ২
  ৩     ২    ১
  
এখন এভাবে যদি আমি এগারোটা বাচ্চার জন্য ঈদের জামা পড়িয়ে দেখতে চাই আমার খবরই আছে – 11! ভাবে ট্রাই করতে হবে। তো সেই জন্যই আছে STL এর নেক্সট পারমুটেশন

    vector< int > v;
for(int i=0; i<11; i++) v.push_back( i );

do {
// protitat jama prottekke porai dekho shukh maximize hochche kina
}while( next_permutation( v.begin(), v.end() ) );
 
আমরা ৩ এর জন্য যেভাবে সবগুলো পারমুটেশন জেনারেট করেছি, সেটাই এই নেক্সট পারমুটেশন করবে। খেয়াল কোর যে, নেক্সট পারমুটেশন কিন্তু ঠিক অ্যালফাবেটিকালি পরের পারমুটেশনটাকে নেয়। তুমি যদি সব পারমুটেশন চাও, প্রথমে অবশ্যই অ্যারেটাকে সর্টেড রেখো।

 রিভার্স

রিভার্স হচ্ছে একটা কিছুকে ধরে উল্টাই দেয়া।
ধরো আমার একটা ভেক্টর আছে।
 

vector< int > nacho;
reverse( nacho.begin(), nacho.end() );

পরের স্টেটমেন্টটা লিখলে, সে নাচোকে উল্টাই দিবে।

তো এই ছিলো ব্যাসিক সি++ আর STL।

C++ STL :: pair

কিছু কথাঃ

যারাই কিনা সি/সি++ নিয়ে বেশকিছুদিন নাড়াচাড়া করছেন, তারা প্রায় সবাই সি এর একটা দারুন জিনিস স্ট্রাকচার-এর সাথে পরিচিত, আর, আরেকটু অ্যাডভান্সডরা তো মনে হয় অলরেডি সি++ এর ক্লাস নামের জিনিসটা মোয়া বানিয়ে ফেলেছে।
সি একটা ফাটাফাটি ল্যাঙ্গুয়েজ আর সি++ এর কথা তো বলাই বাহুল্য। যারা অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং এর সুবাতাস পেয়েছেন তারা এটা আরো ভাল করে জানেন। আমরা জানি, সি++ এ কিছু প্রিমিটিভ ডাটা টাইপ ডিফাইন করা আছে, যাদের উপরে আমরা খুব সহজেই বিভিন্ন অপারেশন চালাতে পারি, কিন্তু মাঝে মাঝে এই রকমের ডাটা টাইপের ব্যবহার আমাদের কে ঝামেলায় ফেলতে পারে। যেমন, মনে করা যাক আমাকে একটা 2D গ্রিডের কিছু পয়েন্ট স্টোর করতে হবে। শুধু int টাইপের অ্যারে দিয়ে এটা মেইনটেইন করাটা বেশ মুশকিলের ব্যাপার। কিন্তু যদি এরকম একটা ডাটা টাইপ থাকতো ‘point’ নামে, যা কিনা (x, y) আকারে কো-অর্ডিনেট রাখতে পারতো!!! সি এ সেই ব্যাবস্থা করেই দেয়া আছে, যেন প্রোগ্রামাররা চাইলেই ইচ্ছা মতো ডাটা টাইপ বানিয়ে নিতে পারেন, আর সি++ এটাকে আরেক ডিগ্রি এগিয়ে নিয়ে গেছে। এখানে প্রোগ্রামার চাইলে তার বানানো ডাটা টাইপের আচার আচরণও বলে দিতে পারেন।
কিন্তু, প্রশ্ন হল, এটা কন্টেস্ট প্রোগ্রামিং এর জন্য কতটা সুইটেবল?

পেয়ার কি?

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

structpoint { int x, y; } P[128];
অর্থাৎ, P[] হল একটা পয়েন্ট টাইপের অ্যারে, এখন এটাকে সর্ট করতে হবে। কাজ তো সোজাই, অ্যালগোরিদমের হেডারটা ইনক্লুড করে sort() মেরে দিলেই হয়… কিন্তু আসলে এটা এত সিম্পল না, কারন, sort() একটা টেমপ্লেট ফাংশন, মানে যে কোন ডাটাটাইপের জন্য কাজ করবে, কিন্তু তার আগে তাকে ডাটাটাইপের ভাবগতি জানাতে হবে। আমি ‘struct point’ দিয়ে কি বুঝাতে চাই, এটা তার বুঝার কোন কারনই নাই যদি না আমি বলে দেই। তার মানে খালি sort() কে ডাকলেই চলবে না, তার সাথে অপারেটর ওভারলোড বা কম্পেয়ার ফাংশন লিখে বুঝিয়ে দিতে হবে যে আমি আসলে কি চাই। আর এখানেই std::pair এর প্লাস পয়েন্ট।
std::pair জিনিশটা তেমন কিছুই না, জাস্ট দুইটা ভ্যালু কে একসাথে করে রাখে, যেখানে ভ্যালু দুইটা যে কোন টাইপের হতে পারে, ডিফারেন্ট টাইপেরও হতে পারে। পেয়ার ক্লাসটা ডিফাইন করা থাকে std <utility> নামের হেডারে।
#include <utility>
using namespace std;
pair ক্লাসের ডেফিনিশনঃ
template <class T1, class T2> struct pair {
    T1 first;
    T2 second;
    pair(): first(T1()), second(T2()) {}
    pair(const T1 &x, const T2 &y): first(x), second(y) {}
    template <class U, class V> pair(const pair<U, V> &p): first(p.first), second(p.second) {}
};
যাদের টেমপ্লেট সম্পর্কে আইডিয়া নাই, তাদের জন্য অল্প কথায়, টেমপ্লেট একটা সিস্টেম যেখানে কোন অ্যাকচুয়াল টাইপের জন্য ডিজাইন থাকে না, বরং যে কোন টাইপের জন্য তার একটা ইন্সট্যান্স তৈরি করা যায়। টেমপ্লেট শিখতে হলেএই পেজটি দেখা যেতে পারে।
pair এর সুবিধা হল, এটা টেমপ্লেট টাইপ, তাই STL algorithm এর ফাংশন গুলার জন্য সাধারনতঃ pair অবজেক্ট গুলার আলাদা করে কোন পরিচয় দেওয়ার দরকার পড়ে না। যেমন আগের প্রবলেমে জাস্ট sort() কল দিলেই চলে, সে অটমেটিক প্রথমে পেয়ারের প্রথম মেম্বার, তার পর ২য় টা, তার পর ৩য় টা, এভাবে বাকি গুলা কম্পেয়ার করে দেখবে। প্রোগ্রামারকে এর জন্য কিছুই বলতে হবে না।

কিভাবে ব্যবহার করে?

pair নিয়ে কাজ করতে চাইলে <utility> হেডার ইনক্লুড করা উচিৎ, অবশ্য যে কোন STL হেডার ইনক্লুড করলেই pair ব্যবহারের সুবিধা পাওয়া যায়। আর pair টাইপের অবজেক্ট সহজে ক্রিয়েট করার জন্য <utility> হেডারের make_pair() ফাংশন ব্যবহার করা যায়। আর pair-এর ১ম আর ২য় এলিমেন্টকে যথাক্রমে .first আর .second মেম্বার দিয়ে অ্যাক্সেস করা যায়। নিচে একটা উদাহরন দেখানো হলঃ
#include <iostream>
#include <string>
#include <utility>
using namespace std;
int main() {
    // simple constructions
    pair< int, int > px, py;
    pair< int, int > p1(23, 43);
    pair< int, int > p2 = pair< int, int >(234, 534);
    px = p1;
    py.first = p2.first * px.second, py.second = p2.second * px.first;
    cout << "py: (" << py.first << ", " << py.second << ")\n";
    
    // bit more complex
    pair< pair< int, int >, pair< int, int > > p3;
    p3 = pair< pair<int, int>, pair< int, int > > (px, py);
    cout << "p3: ((";
    cout << p3.first.first << ", " << p3.first.second << "), (";
    cout << p3.second.first << ", " << p3.second.second << "))\n";
    
    // using make_pair()
    pair< double, pair< string, int > > p4;
    p4 = make_pair(3.14159, make_pair("pi", 5) );
    cout << "this is " << p4.second.first << ", value: " << p4.first;
    cout << " precision: " << p4.second.second << " digits\n";
    return 0;
}
pair নিয়ে সবচেয়ে বেশি যে কথাটা শোনা যায় তা হল, মানুষজন নাকি .first.second.second.first…. এরকম চেইন লিখতে লিখতে টায়ার্ড হয়ে যায়। কিন্তু একটু কাজ করেই এইটাকে সহজ করে ফেলা যায়, যেমন, নিচের কোডে pair কে #define করে নেওয়া হয়েছেঃ
#include <iostream>
using namespace std;
#define pii pair< int, int >
#define ppi pair< pii, int >
#define ff first
#define ss second
int main() {
    ppi p1;
    pii p2;
    cin >> p2.ff >> p2.ss;
    p1 = ppi( p2, p2.ss * p2.ff );
    cout << "entry: " << p1.ff.ff << ", " << p1.ff.ss << endl;
    cout << "product: " << p1.ss << endl;
    return 0;
}
অন্যান্য STL কন্টেইনারের ডাটা টাইপ হিসাবেও pair ব্যবহার করা যায়। যেমন, বি.এফ.এস. অ্যালগরিদমে প্রায়ই কিউতে একজোড়া নাম্বার রাখতে হতে পারে, অথবা ডায়াকস্ট্রার অ্যালগরিদমে পুরা একটা এজকে প্রাইওরিটি কিউতে রাখার ব্যাবস্থা করতে হয়। এটাও খুব সহজেই করা যায়ঃ
#include <queue>
using namespace std;
#define pii pair< int, int >
#define edge pair< int, pii >
// edge.first is weight, edge.second is a pair indicating endpoints
queue< pii > Q;
priority_queue< edge, vector< edge >, greater< edge > > PQ;

সতর্কতাঃ

অন্যান্য সব STL অবজেক্টের মত, এখানেও একটা ব্যাপার খেয়াল করতে হবে তা হলঃ উপরের উদাহরন গুলাতে দেখা যায় কন্সট্রাকশন শেষ করার সময় মাঝে মাঝে পর পর দুইটা > ব্যবহার করতে হয়, (যেমন প্রাইওরিটি কিউ এর উদাহরনে শেষে ……greater< edge > >, এখানে শেষ ২টা > এর মাঝখানে একটা স্পেস ব্যবহার করা হয়েছে, এটা কিন্তু সৌন্দর্য বর্ধনের জন্য না। এটা না দিলে অনেক সময় কম্পাইলারের মাথা গরম হয়ে যায়। কারন সি++ এ >> আরো কয়েকটা অপারেটরের কাজ করে। আর যেসব যায়গায় দেখা যায় pair ইউজ করলে আরো ঝামেলা হয়, সেখানে নরমাল স্ট্রাকচার ব্যবহার করাটাই বেশি ভাল। এটা জেনে রাখা ভাল, আর জানলেই যে বসাতে হবে এমনও কোন কথা নাই।

ব্যবহারঃ

সাধারনতঃ STL এর টেমপ্লেট ক্লাসগুলোর ওভারলোডিং সুবিধা নেওয়ার জন্য এবং ছোটো খাটো স্ট্রাকচারের শর্টহ্যান্ড হিসাবে pair ব্যবহার করা হয়ে থাকে। এছাড়া std::map এ হাশিং এর সময় pair ব্যবহার করা হয়। প্রোগ্রামিং প্রবলেমগুলাতে গ্রাফ আর জিওমেট্রিক রিপ্রেজেন্টেশনে pair অনেক ব্যবহার করা হয়।

সি++ এর প্রাথমিক ধারণা

আমরা যারা কন্টেস্ট প্রোগ্রামার, আমরা যতটা না একজন প্রোগ্রামার তার চে’ অনেক বেশি হচ্ছি একজন প্রবলেম সলভার। আমরা কিন্তু ঠিক প্রথাগত কম্পিউটার সায়েন্টিস্ট ও নই, যারা মোটামুটি একটা কঠিন প্রবলেম পৃথিবীর কোণাকান্চি থেকে খুঁজে বের করে, সেটার পেছনে একটা বছর ধাই করে উড়িয়ে দেবে, তারপর গালটা অনেকক্ষণ চুলকায়ে টুলকায়ে মনে করতে বসবে শেষ কবে দাঁড়ি কাটার সৌভাগ্য হয়েছিল। আবার আমরা ইনডাস্ট্রি প্রোগ্রামারদের মতও নই – যারা মোটামুটি একমাস ধরে একই চুইংগাম চাবাতে চাবাতে একটা বোরিং কোড অলস হাতে বসে বসে লিখতে থাকে। কোড লিখতে লিখতে ঘুমাই পড়ে, আবার ঘুম থেকে উঠে আবার একই কোড লিখতে থাকে।

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

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

এই লেখাটাতে আমি সি++ নিয়ে লিখবো। আর লিখবো কন্টেস্ট প্রোগ্রামারদের ঠিক কতটুকু সি++ জানা দরকার সেটা নিয়ে, আর ঠিক সেইটুকুই। কন্টেস্ট প্রোগ্রামাররা আর সবার মতো না, যে তাদেরকে একটা মোটাসোটা স্বাস্থ্যবান সি++ এর বই ধরিয়ে দিয়ে “নাচো” টাইপের কিছু একটা বলে আমি উধাও হয়ে যাবো। 

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

প্রথম অংশ – সি++ নিয়ে বকরবকর

স্ট্রাকচার

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

আমরা এই জিনিসটাকে বলি স্ট্রাকচার। এটা লিখি অনেকটা এভাবে।

struct data {
    char name[20];
    int number, email_num;
};

অবশ্যই ইমেইল আইডি ইনটেজার হয় না – আমি শুধু বোঝানোর লিখছি।
তো আগে আমাদের কিছু ডাটা টাইপ ছিল int, char, double এই ধরনের। আমরা এইমাত্র আমাদের নিজেদের জন্য একটা ডাটা টাইপ তৈরী করলাম, যার নাম হচ্ছে data । ডাটা হচ্ছে একটা মিষ্টির প্যাকেট যার মধ্যে বিভিন্ন ধরণের অনেকগুলো মিষ্টি আছে।এভাবে চিন্তা করলে যদি দেখো তোমার খুব মিষ্টি খেতে ইচ্ছে করছে, তাহলে চিন্তা করো, data হচ্ছে একটা বাক্স যেটার ভিতর আরো কিছু বাক্স(char, int) আছে।

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

struct day {
    data new_people[100];
    int total_new_people;
    worklist todo[100];
};

যেখানে worklist হয়তো আরেক টাইপের ডাটা। day হলো একটা বাক্স যেটার ভিতরে data  টাইপের কিছু বাক্সও আছে। 

ব্যাপারটা কঠিন লাগছে? হুমম, এটার নামই হলো অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং। যারা প্রথম প্রথম এটা বুঝতে পারে, তারা তার পরের মোটামুটি কয়েক সপ্তাহ যেখানে সেখানে এটা নিয়ে আঁতলামি করতে খুব ভালোবাসে। তো জিনিসটা কঠিন লাগাটাই স্বাভাবিক। 

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

বাক্সে বাক্সে বন্দি বাক্স
বাক্সে বাক্সে বন্দি বাসা,
বাক্স নিয়ে টাক show করা,
বাক্সতে সব স্বপ্ন আশা।

অর্ণবের মত একটা ননকোডার মানুষ যদি এই জিনিস বুঝতে পারে, আমরা কেন পারবো না? আরে, আমরা হলাম গিয়ে কন্টেস্ট প্রোগ্রামার, এলিট ক্লাসের মানুষজন!

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

struct day {    data new_people[100];    int total_new_people;    worklist todo[100];
    void charm_your_miss() {        while( true ) do_math();        while( true ) smile();    }
    void do_math() {        int a, b;        scanf(“%d %d”,&a,&b);        printf(“%d\n”, a+b );    }
    void smile() {        printf(” :) “);    }};
 
এটা হচ্ছে তোমার দিনেরই একটা অংশ, তাইনা? ডাটার পাশাপাশি তোমাকে কিছু কাজও রাখতে হচ্ছে। নাইলে আসলে মিসকে চার্ম করা যাচ্ছে না, এমনকি হাসাও যাচ্ছে না।

এখন যদি আমার শুধু একটা স্ট্রাকচারের কোন একটা ডাটা অ্যাকসেস করা লাগে। আমরা সেটা করি ডট অপারেটর দিয়ে। ধরো আমার শুধু দরকার total_new_people কে। সেটাকে ধরে আমি শুণ্য করে দিবো। তাহলে আমার মেইন এর ভিতর কোডটা হবে এমন।


int main() {    day a_bright_new_day, mora_day;    mora_day.total_new_people = 0;    return 0; // already more gesi! :(}
 

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

int main() {    day a_bright_new_day, mora_day;    while( true ) a_bright_new_day.smile();    return 0; // are baba, din to shesh hobei!}

তো এই হলো ঘটনা।

এখন সমস্যা হলো, প্রতিদিন কতকিছুই ঘটতে পারে। তার উপর ছেলেপুলে বড় হচ্ছে। এখন সবকিছু তো আর সবাইকে বলা যায় না, তো আমরা আসলে সব ডাটা এমন ভাবে রাখতে পারবো না, যে আজাইরা লোকজন এসে বলবে, “চিচিং ফাঁক! এই নাও ডট অপারেটর”, তারপর ডট অপারেটর দিয়ে আমাদের সব ডাটা মেরে দিবে।

এই জিনিসটা এড়ানোর জন্য আমরা একটা কি-ওয়ার্ড ব্যবহার করি। চিচিং ফাঁক এর ঠিক উল্টা। এটা হলো – private। তোমার প্রাইভেট জিনিসপাতিতে কারো সাধ্য নাই হাতাহাতি করার। ;) তো জিনিসটা তখন লিখে এভাবে।

struct day {
    data new_people[100];
    int total_new_people;
    worklist todo[100];
    
    private:
        sweetthings bolbo_keno[100];
   
};

জিনিসপাতি পাবলিক করতে চাইলেও কোন সমস্যা নাই। পাবলিক করে দিলেই হবে। সেটা লিখতে হবে এভাবে।


struct day {    data new_people[100];    int total_new_people;    worklist todo[100];
    public:        sweetthings bolboi_to[100];
};

এবার একটু জ্ঞান কপচাই। সি++ এ, একটা ফাউ জিনিস আছে, সেটার নাম হলো ক্লাস। ক্লাস একটু মুরুব্বি টাইপের জিনিস। একইভাবেই লিখেও যদিও তারপরও।

class day {    data new_people[100];    int total_new_people;    worklist todo[100];
    public:        sweetthings bolbo_na_vabsilam[100];
};

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

ফাংশন ওভারলোড

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

একটা সহজ উদাহরণ হচ্ছে অ্যাবসলুট ভ্যালু নেয়া। কোন সংখ্যার শুধু মান নেয়াটাকে বলে অ্যাবসলুট ভ্যালু নেয়া। যেমন -২০ এর অ্যাবসলুট ভ্যালু হলো ২০। মাইনাস উড়ে গেছে।


int absolute_int( int x ) {    if( x < 0 ) return -x;    else return x;}

তো ধরো আমার long long এও একই কাজ করা লাগবে। তাইলে আমি লিখবো


long long absolute_ll( long long x ) {    if( x < 0 ) return -x;    else return x;}

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


long long absolute( long long x ) {    if( x < 0 ) return -x;    else return x;}int absolute( int x ) {    if( x < 0 ) return -x;    else return x;}

হেডার ফাইল

সি++ এ নেমস্পেস ব্যবহার করলে হেডার লিখার জন্য .h মারা লাগে না। সেটা যদি সি++ এর হয়, যেমন algorithm, তাহলে এটা লেখা হবে এভাবে।

#include <algorithm>
using namespace std;

কিন্তু সেটা যদি সি এর কিছু একটা হয়, আমরা শুরুতে c লিখে দিবো। যেমন stdio.h লেখা হয় এভাবে। 

#include <cstdio>
using namespace std;

সত্যি কথা আমি এসবের কিছুই করি না। আমার একটা জায়গায় যা কিছু মনে পড়ে, যার যার কথা মনে পড়ে, সবাইকে একসাথে লিখে রেখেছি। জাস্ট ধরে কথা বার্তা ছাড়াই একটা কপি মারি।

#include<cstdio>#include<sstream>#include<cstdlib>#include<cctype>#include<cmath>#include<algorithm>#include<set>#include<queue>#include<stack>#include<list>#include<iostream>#include<fstream>#include<numeric>#include<string>#include<vector>#include<cstring>#include<map>#include<iterator>using namespace std;

এই হলো আমার হেডারদের কাহিনী।

কিন কাউট!

আমি অবশ্য উচ্চারণ করি সি-ইন, সি-আউট।
তুমি যদি একজন সি কোডার হও, তুমি অবশ্যই scanf দিয়ে ইনপুট নাও, আর printf দিয়ে আউটপুট মারো। খুব স্বাভাবিক ব্যাপার, আরে এতে লজ্জা পাওয়ার কিচ্ছু নেই, সবাই তাই করে! কিন্তু ব্যাপারটা হলো, সি তে তোমাকে বলে দিতে হয় তুমি কি ধরণের ডাটা নিয়ে খেলছো, মনে রাখতে হয় %lld, %lu, %c, %s, %d, %lf এইরকম বিচ্ছিরি দেখতে অনেক অনেক কিছু। 

সিপিপিতে তুমি শুধু একটা সি-ইন মেরে দিবা, কিচ্ছু মনে রাখা লাগবে না।
যেমন এটা হলো একটা সি কোড

int main() {
    int murgi;
    double water;
    long long bank_balance;
    
    scanf(“%d %lf %lld”,&murgi, &water, &bank_balance);
    printf(“%d %lf %lld”,murgi, water, bank_balance);    

 return 0;
     
}

একই জিনিস সি-ইন সি-আউট দিয়ে লিখলে এরকম হবে। 

int main() {    int murgi;    double water;    long long bank_balance;
    cin  >> murgi >> water >> bank_balance;    cout << murgi << water << bank_balance;
    return 0; // ki ase jibone?

খালি একটাই সমস্যা। এরা একটু স্লো। কাম কাজ একটু বেশি ধীরে সুস্থ্যে করে। 

টেম্প্লেট

টেম্প্লেট কি জিনিস সেটা যদি তুমি বুঝতেই চাও, এই কোডটায় একটা উঁকি মারো। ভয় পেয়েছো? এটা হলো পৃথিবীর এখনকার এক নাম্বার কোডারটার কোড।

template<class T> inline T gcd(T a,T b)

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


template<class T> T absolute( T x ) {
    if( x < 0 ) return -x;
    else return x;
}


মানে আমার দুই তিনবার একই ফাংশন আলাদা আলাদা করে ডাটাটাইপ পাল্টে লিখতে হতো না। আমি টেম্প্লেটটা দেখিয়ে নিলাম, এই জন্য যে, আমরা একটু পরে STL নিয়ে আঁতলামি শুরু করবো, STL এর সবকিছুতে টেম্প্লেট ব্যবহার করে লেখা, যাতে তুমি ইচ্ছামতো ক্লাস/স্ট্রাকচার ব্যবহার করে নিজের ডাটাটাইপ ব্যবহার করতে পারো, আর সেটা নিয়ে ইচ্ছামতো নাচানাচিও যেন করতে পারো।

C প্রোগ্রামিং বিট , বাইট , মেমোরি এড্রেস , কম্পাইলার

কেমন আছেন সবাই ? আবার দেখা হইয়ে গেলো C programing পোস্টে  এ । আগের পোস্টে এ আমি আপনাদের C Programing কি , কেন শিখবো এইসব ব্যাপারে বলেছিলাম । তবে C Programing শিখার জন্য আর অনেক কিছু জানার দরকার । আজকে আলোচনা করবো বিট, বাইট , কম্পাইলার ইত্যাদি বিষয়ে । তাহলে আর কথা না বাড়াই ।

বিট এবং বাইট কি ?

বিট এবং বাইট হল কম্পিউটার এর বিভিন্ন ডাটার অতিক্ষুদ্র একক । কম্পিউটার সাধারণত '০' আর '১' নিয়ে কাজ করে । অর্থাৎ কম্পিউটার বাইনারি পদ্ধতিতে কাজ করে । আর এই বাইনারি সিস্টেমে প্রতিটি ডাটার একক হল বিট । কিন্তু এই বিট কে শুধুমাত্র '০' আর '১' এর মাধ্যমে প্রকাশ করা যায় ।

তাই বাইনারি সিস্টেমের এই সীমাবদ্ধতাকে কাটানোর জন্য কতগুলু বিটকে এক করে ব্যাবহার করা হয় যাকে বলে বাইট । ৮ বিট = ১ বাইট  । অর্থাৎ ৮ টা বিট মিলে হয় ১ বাইট । অর্থাৎ যদি বলা হয় যে কোন Software মেমোরিতে যদি 5MB জায়গা দখল করে তার মানে হল যে সে মেমোরিতে ১০২৪*১০২৪*৫ বাইট  জায়গা দখল করল ।
  • ৮ বিট = ১ বাইট
  • ১০২৪ বাইট  = ১ কেবি
  • ১০২৪ কেবি = ১ এমবি
  • ১০২৪ এমবি = ১ জিবি
  • ১০২৪ জিবি = ১ টেরা বাইট
মনে রাখা দরকার যে কম্পিউটার একটা  অক্ষর রাখার জন্য মাত্র ১ বাইট  জায়গা নিবে ।
C programing

মেমোরি এড্রেস কি ?

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

এখন কথা হল C প্রোগ্রাম লিখব কোথায় ? C প্রোগ্রাম লিখতে হলে আমাদের Compiler লাগবে ।

কম্পাইলার এবং ইন্টারপ্রিটার কি ?

আমরা জানি যে কম্পিউটার সুধু  মেশিন Language বুঝে । কিন্তু C Programing Language তো কম্পিউটার এর বোধগম্য না । তাই এমন কিছুর দরকার যেইটা কিনা এই ভাষা কে কম্পিউটার এর বোধগম্য করে দিবে । আর সেইতা করার জন্য আমাদের দরকার কম্পাইলার / ইন্টারপ্রিটার ।  কম্পাইলার  যেকোনো প্রগ্রামিং Language কে Computer Machine Language এ রুপান্তরিত করে তাকে কম্পিউটার এর ব্যাবহার উপযোগী করে তোলে । এখন কথা হল গিয়ে কম্পাইলার আর ইন্টারপ্রিটার যেহেতু একই কাজ করে তাহলে এদের মধ্যে পার্থক্য টা কোথায় ।
কম্পাইলার C Programing Language কে Compile করে তাকে Machine Code এ Convert করে Executable File তৈরি করে যা পরবর্তীতে সহজভাবে কোন কম্পাইলার ছাড়াই ব্যাবহার করা যায় ।কিন্তু Interpreter সম্পূর্ণ Code কে Machine Code এ রূপান্তরিত করে না যার ফলে প্রতিবার প্রোগ্রাম ব্যাবহারের জন্য Interpreter এর দরকার পরে ।আর তাছাড়া কম্পাইলার ইন্টারপ্রিটার থেকে অনেক দ্রুত কাজ করে । তাই ইন্টারপ্রিটার থেকে কম্পাইলার অনেক বেশি জনপ্রিয় ।

এখন কথা হল গিয়ে কি ধরনের Compiler ব্যাবহার করা ভাল । অনেক ধরনের Compiler আছে । আমার জানামতে বর্তমানে সবচেয়ে ভাল Compiler গুলুর মধ্যে
CodeBlock , Dev C++ , NetBeans IDE এবং Microsoft Visual Studio ই উল্লেখযোগ্য ।
আজকে এই পর্যন্তই । আবার দেখা হবে ।
========================= HAPPY PROGRAMING ==============================

C প্রোগ্রামিং কি,কেন এবং কিভাবে শিখবো

কেমন আছেন সবাই ? আজকে অনেক দিন পরে  Blogspot এ বসলাম পোস্ট করার জন্য । আপনাদের সামনে C প্রোগ্রামিং এর চেইন টিউন নিয়ে আসলাম । দুঃখের হলেও সত্য যে পূর্বে অনেকেই  টিউন করেছেন C প্রোগ্রামিং নিয়ে কিন্তু সময়ের অভাবে হোক আর যে কারনেই হোক  অনেকেই মানে সবাই ই পুরাপুরি শেষ করতে পারেননি ।
যাই হোক পূর্বে যারাই করার চেষ্টা করেছেন তাদের প্রতি কৃতজ্ঞতা জানিয়ে আজকে থেকে আমার C প্রোগ্রামিং চেইন টিউন শুরু করলাম । এই চেইন টিউন এ আমি আপনাদের সবার  সহযোগিতা কামনা করছি । যাই হোক কথা না বাড়িয়ে কাজে নামি । আজকের প্রথম পর্বে আমি C প্রোগ্রামিং কি , কেন আমাদের প্রোগ্রামিং করা দরকার এবং কিভাবে করা যায় ইত্যাদি বিষয় নিয়ে আলোচনা করব ।

C প্রোগ্রামিং কি ?

প্রথমেই আমাদের জানতে হবে যে C প্রোগ্রামিং কি । প্রযুক্তির আজকের এই পর্যায়ে এসে কাররই অজানা থাকার কথা না যে C প্রোগ্রামিং কি । তারপরেও বলি C একটি কম্পিউটার প্রোগ্রামিং ভাষা । আমাদের মানুষদের যেমন ভাষা আছে তেমনি কম্পিউটার এর ও নির্দিষ্ট ভাষা আছে । আর ও বিভিন্ন কম্পিউটার প্রোগ্রামিং ভাষা আছে । তাদের মধ্যে C++, Java , Python , C#, COBOL , ASP.NET , Objective-C , PHP , Ruby ইত্যাদি অন্যতম ।
C কে বলা হয় "Mother of Computer Programing" । C প্রোগ্রামিং Language আবিষ্কৃত হয় ১৯৭২ সালে Dennis Ritchie এর মাধ্যমে । বর্তমানে C 11 হল সর্বশেষ আপডেট । বর্তমানে যত প্রোগ্রামিং ভাষা আছে তার প্রায় সবগুলাই C এর উপর ভিত্তি করে তৈরি করা । বর্তমানে সবচেয়ে জনপ্রিয় Social Networking Website " Facebook " তাদের নতুন প্রোগ্রামিং Language Hack রিলিজ করল । Google ও তাদের নিজস্ব Programing Language DART রিলিজ করল ।
C programing

C প্রোগ্রামিং কেন শিখবো ?

আজকের এই প্রযুক্তির দিনে আমার নিশ্চয়ই প্রোগ্রামিং শিখার গুরুত্তের কথা বলা লাগবেনা । অনেকেই বলেন যে আজকাল এত উন্নত প্রোগ্রামিং ল্যাঙ্গুয়েজ থাকতে C কেন শিখবো ? তাছাড়া C Language এ আবার OOP (Object Oriented Programing) এর সুবিধাও নেই । তাহলে C কেন শিখবো ? আমাদের ভুলে গেলে চলবেনা যে আজকে যত উন্নত প্রোগ্রামিং ভাষা আছে তার সবগুলাই C কে ভিত্তি করেই এসেছে । তবে এটা আমার যুক্তি নয় । যে কোন কেও যে কোন Programing Language দিয়ে Programing শেখা শুরু করতে পারে ।
কিন্তু C programing Language এর Data Structure , Memory Management , Array , Function এগুলা বুজতে পারলে বাকি Language গুলা অনেক সহজ হইয়ে যাবে । যেমন Java Language মূলত C Based Programing Language । কিন্তু জাভা এর Syntax  C Language থেকে অনেক আলাদা । যার কারনে জাভা জেনেও অনেকে C++ করতে গিয়ে হিমশিম খায় । এর মুল কারন হচ্ছে syntax গত তফাৎ । কিন্তু কেও যদি C Programing Language তা আয়ত্ত করতে পারে তাহলে তার জন্য C++,Python , C# শিখাটা অনেক তরান্বিত হবে । কারন এইসব Language হল C Based । তাই আমার মতে প্রথম এ C শিখে পরে যেকোনো Programing Language শুরু করা যেতে পারে ।

C প্রোগ্রামিং দিয়ে কি  কি করা যায় এবং কোথায় শিখা যাবে ?

C Programing Language দিয়ে কি না করা যায় । Anti-Virus , Virus , Operating system , Application Software থেকে শুরু করে সবকিছুই করা সম্ভব । সর্ব প্রথম Unix operating system তৈরি করা হইসিল C Language দিয়ে । আর কোথায় শিখার যে বেপারটা সেটা বলতে গেলে বলব যে শিখার জন্য Source এর অভাব নেই শুধু আগ্রহ টা থাকতে হয় । আপনি বাজার থেকে বিভিন্ন রাইটারের বই কিনে শিখতে পারেন । আজকের দিনে Online এও অনেক resource আছে । যেমন তাদের মধ্যে tutorialspoint.com , cprograming.com learn-c.org , programiz.comঅন্যতম । তাহলে দেরি না করে এখনি শুরু করুন ।
HAPPY PROGRAMING
আল্লাহ হাফেয । ভাল লাগলে জানাবেন ।