Array : সাধারণ আলোচনা

Array শব্দটি ইংরেজিতে ব্যবহার করা হয় ধারাবাহিক ভাবে সজ্জিত একটি সমাবেশকে বুঝানোর জন্য। যেমন, array of computer workstations বলতে বুঝায় পাশাপাশি সাজানো অনেকগুলি ডেস্কটপ কম্পিউটার এর একটি সমাবেশকে, ঠিক যেমন স্কুল, কলেজ বা ইউনিভার্সিটির কম্পিউটার ল্যাবে সাজানো থাকে।

প্রোগ্রামিং ল্যাংগুয়েজ এর পরিভাষায়, array হচ্ছে একই ডেটা টাইপের অনেকগুলো ডেটার একটি ধারাবাহিক সমাবেশ।

উপরের সংগা থেকে, কয়েকটা জিনিস স্পষ্ট যে,
১. array হচ্ছে একই ডেটা টাইপের ডেটার সমাবেশ
২. এই সমাবেশে বেশ কিছু ডেটা থাকবে।
৩. এই ডেটা সমূহ ধারাবাহিক ভাবে পাশাপাশি কম্পিউটার মেমরিতে সাজানো থাকে।

আমরা জানি, C ভাষায় যে কোন ডেটা কম্পিউটার মেমরিতে রাখার জন্য ভ্যারিয়েবল ডিক্লেয়ার করতে হয়। array হচ্ছে একই ধরনের অনেকগুলি ভ্যারিয়েবল এর মত।

একটি array কম্পিউটার মেমরিরে তার ডেটা টাইপ অনুযায়ী একটি নির্দিষ্ট পরিমান জায়গা দখল করে থাকে। এই জায়গার পরিমান তার ডেটা টাইপ ও আমরা কতগুলো ডেটা ঐ array তে রাখতে চাই তার উপর নির্ভর করে।

array ব্যবহার করা হয়, একই ধরনের ডেটা গুলোকে তালিকা আকারে সাজিয়ে রাখার জন্য। ধারাবাহিকভাবে সাজানো থাকে বলে এই তালিকা থেকে একটি নির্দিষ্ট ডেটাকে সহজে খুজে পাওয়া যায়, এবং সহজে ব্যবহার করা যায়।

ডিক্লেয়ারেশন


সাধারণ ভ্যারিয়েবল এর মতই array ডিক্লেয়ার করার সময় প্রথমে তার ডেটা টাইপ উল্লেখ করতে হয় এবং তারপর তার নাম দিতে হয়। তবে নামের সাথে বিশেষ পদ্ধতিতে, ঐ array তে কতগুলি ডেটা থাকবে সেটাও উল্লেখ করে দিতে হয়। নামের সাথেই থার্ড ব্রাকেট '[]' এর মধ্যে ঐ array এর উপাদান সংখ্যা নির্ধারণ করে দিতে হয়। যেমন, আমরা যদি ১০০ জন ছাত্রছাত্রীর পরীক্ষায় প্রাপ্ত নম্বর রাখার জন্য একটি array ডিক্লেয়ার করতে চাই, তাহলে আমাদের int টাইপের একটি array ডিক্লেয়ার করতে হবে যার উপাদান সংখ্যা হবে ১০০। যদি array টির নাম marks হয়, তাহলে ডিক্লেয়ারেশন স্টেটমেন্ট হবে,

int marks[100];

খেয়াল রাখতে হবে যে নাম আর [ এর মধ্যে যেন কোন স্পেস বা ফাকা জায়গা না থাকে।

উপরের marks array টি ১০০ টি ইন্টিজার ভ্যারিয়েবল এর সমাবেশ হিসেবে কাজ করে।

এখন আমরা ইচ্ছে করলে এই array এর একটি একটি করে ডেটা বা উপাদানকে এক্সেস করতে পারবো। array এর একটি উপাদানকে এক্সেস করার পদ্ধতিকে ইন্ডেক্সিং বলে। আর ঐ array তে ঐ উপাদানের ক্রমিক নম্বরকে তার ইন্ডেক্স নম্বর বলে। ইন্ডেক্স নম্বর শুরু হয় 0 (শূন্য) থেকে। কম্পিউটার বিজ্ঞানে গণনা সাধারণত শূন্য থেকেই শুরু হয়। কাজেই, কোন array এর প্রথম উপাদানের ইন্ডেক্স নম্বর হবে শূন্য। আর শেষ উপাদানের ইন্ডেক্স নম্বর হবে array এর আকারের চেয়ে ১ কম। উপরের marks array তে  0 থেকে 99 পর্যন্ত মোট ১০০ টি ইন্ডেক্স আছে।

array এর নামের পরে থার্ড ব্রাকেট এর মধ্যে ইন্ডেক্স নম্বর দিয়ে ঐ ইন্ডেক্সে রক্ষিত ডেটা এক্সেস করা যায়। যেমন,

marks[0] বলতে বোঝায় প্রথম ইন্ডেক্সে রক্ষিত ডেটাকে, marks[50] বলতে বোঝায় ৫১তম ইন্ডেক্সে রক্ষিত ডেটাকে।

আমরা যদি এই array টির ক্ষেত্রে marks[100] লিখি, তাহলে সেটা ভুল হবে। কারণ এই array তে ১০০ নম্বর ইন্ডেক্স বলে কিছু নেই। তাই সেটি এক্সেস করাও সম্ভব না।

array নিয়ে কাজ করার সময় সর্বদা সতর্ক থাকতে হবে যেন ইন্ডেক্সিং সঠিকভাবে করা হয়। অন্যথায় প্রোগ্রাম ক্রাশ করবে।

ইনিশিয়ালাইজেশন


অন্যান্য ভ্যারিয়েবল এর মত ডিক্লেয়ারেশন এর সময় array কে এসাইনমেন্ট অপারেটর ব্যবহার করে ইনিশিয়ালাইজ করা যায়। এই ক্ষেত্রে একটি কার্লি ব্রেসের মধ্যে কমা দিয়ে আলাদা করা ডেটার তালিকা array তে এসাইন করলেই ঐ ডেটা ধারাবাহিকভাবে array এর বিভিন্ন ইন্ডেক্সে একই ক্রমে কপি হয়ে যায়।

যেমন,

int num[5]={1, 2, 3, 4, 5};

স্টেটমেন্ট টি num নামে ৫ ইন্ডেক্সের একটি ইন্টিজার array ডিক্লেয়ার করে এবং তার 0 থেকে 4 নম্বর ইন্ডেক্সে যথাক্রমে 1, 2, 3, 4, 5 জমা রাখে।

array কে মোট ইন্ডেক্স সংখ্যা ছাড়া ডিক্লেয়ার করা যায় না। যেমন,

int num[];

ডিক্লেয়ারেশন স্টেটমেন্ট টি ভুল।

তবে যদি ডিক্লেয়ার করার সময় ইনিশিয়ালাইজ করা হয় তাহলে array কে মোট ইন্ডেক্স নম্বর ছাড়াও ডিক্লেয়ার করা যায়।

যেমন,

int num[]={1, 2, 3, 4, 5, 6};

স্টেটমেন্টটি সঠিক। এই ক্ষেত্রে কম্পাইলার array টিকে ইনিশিয়ালাইজ করার সময় কার্লি ব্রেস এর মধ্যে থাকা মোট ডেটার সংখ্যাকে ঐ array এর মোট ইন্ডেক্স সংখ্যা হিসেবে নির্ধারণ করে দেয়।


এসাইনমেন্ট অপারেটর ও array


 array একটি ভ্যারিয়েবল সমাবেশ মাত্র, এটি নিজে একটি ভ্যারিয়েবল নয়। তাই, দুটি array একই টাইপের ও একই আকারের হলেও একটি array কে অন্য array তে এসাইন করা যায় না। যেমন,

int num[10], odd[10];

odd=num; /* এই স্টেটমেন্টটি ভুল */

array এর একটি ইন্ডেক্স একটি ভ্যারিয়েবল এর মত কাজ করে। তাই একটি একটি করে ইন্ডেক্স এসাইনমেন্ট অপারেটর ব্যবহার করে কপি করা যায়। যেমন,

int num[5], odd[5];

num[0]=odd[0];
num[1]=odd[1];

এভাবে এসাইন করা যায়।

একটি array এর সব তথ্য অন্য একটি array তে এসাইনমেন্ট অপারেটর ব্যবহার করে কপি করতে চাইলে, একটি একটি করে সবগুলো ইন্ডেক্স এসাইন করতে হবে। এই ক্ষেত্রে দ্বিতীয় array টিকে অবশ্যই প্রথম array এর সমান বা তার চেয়ে বড় হতে হবে। কারণ, আগেই বলা হয়েছে যে ইন্ডেক্স যে array তে নাই, সেই ইন্ডেক্সে এসাইন করা বৈধ নয়।

লিনিয়ার বা সিকোয়েন্সিয়াল সার্চ

লিনিয়ার বা সিকোয়েন্সিয়াল সার্চ একেবারে মৌলিক একটি সার্চ এলগোরিদম। নাম অনুযায়ীই এটি একটি ডেটা স্ট্রাকচারের উপাদানগুলিকে পর্যায় ক্রমে খুঁজে খুঁজে কাংক্ষিত উপাদানটি খুজে বের করে। অবিন্যস্ত ডেটা বা এমন ডেটা যা কোন নির্দিষ্ট ক্রমে সজ্জিত নয়, তার ক্ষেত্রে এটিই একমাত্র সার্চ টেকনিক তবে এটি বেশ সময় সাপেক্ষ।



লিনিয়ার সার্চের মূল ধারণাটি খুব সহজ। আমরা একদম প্রথম উপাদান থেকে খোজা শুরু করবো। এবং যতক্ষন কাংক্ষিত উপাদানটি খুজে পাওয়া না যায় ততক্ষণ খোজ চলতে থাকবে।
লিনিয়ার সার্চ

আমাদের পরিচিত ডেটা স্ট্রাকচার array দিয়েই আমরা উদাহরণটি দিই। ধরা যাক, ১২ টি ভিন্ন সংখ্যা একটি array তে রাখা আছে। আমরা এই array তে লিনিয়ার সার্চ চালিয়ে দেখবো যে এখানে 25 সংখ্যাটি আছে কি না। ধরি, এই array তে সংখ্যাটি নেই। সেই ক্ষেত্রে 0 নম্বর ইন্ডেক্স থেকে 11 নম্বর ইন্ডেক্স পর্যন্ত সার্চ চলবে।



আবার ধরা যাক একটি array তে ১৫ টি ইন্ডেক্স এ 1-15 পর্যন্ত সংখ্যাগুলো আছে। আমাদের সেখান থেকে 9 কে খুজে বের করতে হবে। এই ক্ষেত্রেও আমরা 0 নম্বর ইন্ডেক্স থেকে খোজা শুরু করবো, এবং 8 নম্বর ইন্ডেক্স পর্যন্ত সার্চ চালিয়ে গেলে আমরা আমাদের কাংক্ষিত সংখ্যা 9 খুজে পাবো।


আমাদের কাজের ধাপ হবেঃ

১. 0 ইন্ডেক্স এ খুজে দেখা হবে।
২. যদি কাংক্ষিত সংখ্যা খুজে না পাওয়া যায় এবং এটিই শেষ ডেটা উপাদান না হয় তাহলে ইন্ডেক্স সংখ্যা ১ বৃদ্ধি পাবে এবং আবার ১ নং ধাপে ফেরত যাওয়া হবে। এটিই শেষ ডেটা উপাদান হলে সার্চ থেমে যাবে এবং খুজে পাওয়া যায় নি এমন মেসেজ দেওয়া হবে। যদি কাংক্ষিত সংখ্যা খুজে পাওয়া যায় তাহলেও সার্চ থেমে যাবে এবং খুজে পাওয়া গিয়েছে এমন মেসেজ দেওয়া হবে।

এইবার একটি সহজ কোড দেখি। ধরি array[20] একটি array যেখানে ২০ টি সংখ্যা আছে এবং আমাদের খুজে বের করতে হবে যে কত নম্বর ইন্ডেক্সে 75 সংখ্যাটি আছে।

#include<stdio.h>

int main()
{
    int i,array[20] = {2,3,5,6,33,45,6,34,57,55,75,89,4,6,7,86,54,32,99,78};

    for (i=0; i<20; i++)
    {
        if (array[i]==75)
        {
            printf("Found at index %d", i);
            break;
        }
     }
     if (i==20)
         printf("Not found in any index.");

    return 0;
}

একটি বাক্য থেকে শব্দ গণনা

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

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

এইবার শব্দ খোজার পালা। আর এখানেই আমাদের দরকার লিনিয়ার বা সিকোয়েন্সিয়াল সার্চ সম্পর্কে ধারণা। যাদের এই ধারণাটা নাই তারা দয়া করে এখান থেকে পড়ে আসেন।

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

I love you.

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

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

আমি একটি শর্ত সাজেস্ট করি।

১. আমরা একেবারে শুরুর ইন্ডেক্স থেকে গননা শুরু করবো না। আমরা ১ নম্বর ইন্ডেক্স থেকে গননা শুরু করবো।
২. আমরা তিনটা জিনিসের দিকে নজর রাখবো। স্পেস, স্পেশাল ক্যারেকটার আর নাল টার্মিনেটর।

৩. এদের যে কোন একটাকে খুঁজে পেলে চেক করে দেখবো যে তার আগের ইন্ডেক্সে একটি এলফাবেট বা নাম্বার আছে কি না। যদি এলফাবেট থাকে তাহলে আমরা ধরে নিবো যে একটা শব্দ (হিসাবে সুবিধার জন্য আমরা ধরে নিচ্ছি যে সংখ্যা বা সংখ্যাযুক্ত শব্দও শব্দ) আমরা পেয়ে গেছি। আর যদি তা না হয় তাহলে আমরা পরবর্তি ইন্ডেক্সে সার্চ চালিয়ে যাবো।

কাজেই আমাদের কোড এর গঠন হবে,

#include<stdio.h>
#include<ctype.h>

int main()
{
    char str[128],  ch; /* স্ট্রিং ধারণের জন্য array */
    int i, word=0;

    /* ইনপুট অংশ শুরু */
    for (i =0;;)
    {
        ch=getchar();
        if (ch=='\n')
        {
            str[i]='\0';
            break;
         }
         str[i++]=ch;
    }
    /* ইনপুট অংশ শেষ */

    /* সার্চ শুরু */
    for (i =1; ; i++)
    {
        if (str[i]==' '||ispunct(str[i])||str[i]=='\0') /* স্পেস, স্পেশাল ক্যারেকটার ও নাল টার্মিনেটর চেক */
        {
            if (isalnum(str[i-1])) /* আগের ক্যারেকটার টি এলফাবেট বা ডিজিট কি না সেটা চেক */
            word++;

            if (str[i]=='\0')
            break;
        }
    }
    printf("Number of words = %d", word);

    return 0;
}

দেখুন তো আপনারা চিন্তা করে অন্য একটি উপায় বের করতে পারেন কি না!!!

মৌলিক সংখ্যা : সংখ্যার মৌলিকতা পরীক্ষা

ড্রাফট পোস্টঃ


প্রাইম নাম্বার হল তারা যারা কেবল ১ এবং সেই নাম্বার দ্বারা নিঃশেষে বিভাজ্য। সহজ ও সুন্দর সংগা।



কাজেই আসো আমরা একটা নাম্বার প্রাইম কি না তা বের করার যৌক্তিক পদক্ষেপ গুলো নির্ধারণ করি।

ধারনা ১:

আমরা সংখ্যাটিকে প্রথমে ২ দিয়ে ভাগ করা শুরু করতে পারি। এরপর ৩, তারপর ৪, এভাবে সেই সংখ্যাটির আগ পর্যন্ত সকল সংখ্যা দ্বারা ভাগ করে দেখতে পারি যে কোন ভাগ শেষ আসে কি না। যেহেতু ১ দ্বারা সকল সংখ্যা বিভাজ্য এবং যেকোন সংখ্যাই সেই সংখ্যা দ্বারা বিভাজ্য তাই আমরা ২ থেকে শুরু করে সংখ্যাটির আগের সংখ্যা দ্বারা ভাগ করে দেখতে পারি।

কাজেই আমাদের ইনপুট নাম্বার যদি হয় n তাহলে আমরা 2 থেকে শুরু করে n-1 পর্যন্ত ভাগ করব। এই জন্য আমাদের for স্টেটমেন্ট হবে:

for (i =2; i <n;i++)
{
    flag=1;
    if(n%i==0)
    {
        flag=0;
        break;
    }
}

এরপরে আমরা খুব সহজেই flag এর ভ্যালু চেক করে বলতে পারব যে সংখ্যাটি প্রাইম কি না। কারণ আমরা প্রথমেই ধরে নিয়েছি যে flag এর ভ্যালু  ১ এবং সংখ্যাটি i এক কোন মান দ্বারা বিভাজ্য না হলে flag এর মান ১ ই থাকবে।

এই ধারনা দ্বারা ১ থেকে ৩৫০০০০ এর মধ্যেকার সকল প্রাইম নাম্বার (২৯৯৭৭ টি) বের করতে সময় লেগেছে ১১.৮৬ সেকেন্ড। (সময় নির্ধারণঃ ideone)

ধারণা ২:

আমরা ধারণা ১ কে একটু ঘষামাজা করি।
১০/১০=১, ১০/৫=২;
৮/৮= ১, ৮/৪=২;
..........................
n/n =1, n/(n/2)=2;

তাই কোন সংখ্যা তার অর্ধেকের বেশি মানের কোন সংখ্যা দ্বারা নিঃশেষে বিভাজ্য হতে পারে না।

তাই সেই সংখ্যার অর্ধেকের বেশি মানের কোন সংখ্যা দ্বারা তাকে ভাগ করা অর্থহীন।

কাজেই আমরা ২ দ্বারা ভাগ করা শুরু করব এবং সংখ্যাটির অর্ধেক মানের সংখ্যা দ্বারা ভাগ করেই থেমে যাবো। আমাদের for স্টেটমেন্ট হবে:

for(i =2; i <=n/2; i++)
{
    flag =1;
    if(n%i==0)
    {
        flag=0;
        break;
    }
}

ধারণা ২ তে আমাদের ভাগের কাজ হবে ধারণা ১ এর প্রায় অর্ধেক। এই যুক্তি ব্যবহার করে ১-৩৫০০০০ এর মধ্যেকার সব প্রাইম নাম্বার (২৯৯৭৭ টি) বের করতে সময় লেগেছে ৫.৯৪ সেকেন্ড। (সময় নির্ধারণঃ ideone)

ধারণা ৩:

আমরা ধারনা ২ কে আরো একটু স্লিম করার চেষ্টা করি। কেমন?

* সংগা অনুসারে ২ বাদে আর কোন জোড় প্রাইম নাম্বার থাকা সম্ভব না।
* একটি জোড় সংখ্যা সব সময়ই ২ দ্বারা বিভাজ্য
* একটি জোড় ও একটি বিজোড় সংখ্যার গুনফল সব সময়ই একটি জোড় সংখ্যা।

কাজেই কোন সংখ্যা যদি ২ দ্বারা বিভাজ্য না হয় তাহলে তাকে কোন জোড় সংখ্যা দ্বারা ভাগ করে দেখা অর্থহীন।

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

কাজেই আমাদের লজিক হবে:


flag=1;
if (n==2)
    flag=1;
else if (n%2==0)
    flag=0;
else
    for (i = 3; i <=n/2; i += 2)
    {
        if(n%i==0)
        {
            flag=0;
            break;
        }
    }

ধারণা ৩ এ ভাগের কাজ হবে ধারণা ২ এর অর্ধেক। এই ধারনা ব্যবহার করে ১-৩৫০০০০ পর্যন্ত সব প্রাইম নাম্বার (২৯৯৭৭ টি) বের করতে সময় লেগেছে ২.৯৮ সেকেন্ড। (সময় নির্ধারণঃ ideone)

ধারণা ৪:

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

এখন একটা মজার জিনিস দেখি। ধরা যাক, ১০০ সংখ্যাটি প্রাইম কি না তা আমরা বের করবো। কাজেই ১০০ থেকে ছোট কোন প্রাইম দ্বারা যদি এটি বিভাজ্য না হয় তাহলেই এটি প্রাইম হবে। সবচে ছোট প্রাইম ২। ১০০/২=৫০। ৫০ এর কাছাকাছি প্রাইম হচ্ছে ৪৭। তাই ২ থেকে ৪৭ পর্যন্ত সংখ্যা দ্বারা যদি ১০০ বিভাজ্য না হয় তাহলেই ১০০ প্রাইম।

মজার জিনিসটা হচ্ছে, কোন সংখ্যা যদি প্রাইম না হয় তবে তা তার বর্গমূলের সমান বা তার চেয়ে ছোট কোন না কোন প্রাইম দ্বারা বিভাজ্য। আলোচ্চ্য ১০০ এর ক্ষেত্রে, ১০০ এর বর্গমূল ১০। তাই ২ থেকে ১০ এর মধ্যে কোন সংখ্যা দ্বারা যদি এটি বিভাজ্য না হয় তাহলেই এটি প্রাইম।

১০০ এর কাছাকাছি প্রাইমটি হচ্ছে ৯৭। ২, ৩, ৫, ৭  এই চারটি প্রাইমের কোনটি দ্বারাই ৯৭ বিভাজ্য নয়।

কাজেই,
আমরা যদি কোন সংখ্যার বর্গমূল বের করি এবং ২ থেকে শুরু করে সেই বর্গমূল পর্যন্ত সবগুলো সংখ্যা দিয়ে প্রদত্ত সংখ্যাটিকে ভাগ করে দেখি যে ভাগশেষ শূন্য নয়, তবেই সেটি প্রাইম নম্বর।

আমরা এখন ধারণা ৩ এর সাথে এই ধারণাটা যুক্ত করবো।

অর্থাৎ,


if (n==2)
    flag=1;
else if (n%2==0)
    flag=0;
else
{
    flag=1;
    m= (int) sqrt( (double) n);
    for (i = 3; i <=m; i+=2)
    {
        if (n%i==0)
        {
            flag=0;
            break;
        }
    }
}

এখন flag এর ভ্যালু চেক করলেই বোঝা যাবে যে n প্রাইম কি না।

এই ক্ষেত্রে সময় ধারনা ৩ এর চেয়েও কম লাগবে। এবং সেই কমটাও অনেক অনেক কম।

ধারণা ৪ ব্যবহার করে ১-৩৫০০০০ পর্যন্ত সবগুলো প্রাইম (২৯৯৭৭ টি) বের করতে সময় লেগেছে ০.০২ সেকেন্ড। (সময় নির্ধারণঃ ideone)

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

C কিওয়র্ড সমূহ : C Keywords

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

মোট কথা, কিওয়র্ড হল কোন ভাষার নির্দিষ্ট কিছু শব্দ যাদের কাজ ঐ ভাষার ব্যাকরণ অনুযায়ী পূর্ব নির্ধারিত এবং যারা অপরিবর্তনীয়।



ANSI স্ট্যান্ডার্ড অনুযায়ী C ভাষায় ৩২ টি কিওয়র্ড আছে। এই ৩২ টি কিওয়র্ড ও এদের ব্যবহারের ব্যাকরণ নিয়ে ANSI C ভাষাটি গঠিত। ৩২ টি কিওয়র্ড হলঃ

auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while

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

  • প্রোগ্রামের প্রবাহ নিয়ন্ত্রক (flow control): এই কিওয়র্ডগুলো কোন প্রোগ্রামে কোড এক্সেকিউশনের ধারা ও ধারাবাহিকতা নিয়ন্ত্রন করে। এদেরকে আবার তিনটি উপশ্রেণী তে বিভক্ত করা যায়ঃ


            1. ব্রাঞ্চিং কিওয়র্ডঃ এরা হচ্ছে C এর মাল্টিপল সিলেকশন বা বহুমুখী পথ নির্বাচন সম্পর্কিত কিওয়র্ড। এরা নির্দিষ্ট শর্তের উপর নির্ভর করে কোন কোড এক্সেকিউট হবে, আর কোন কোড এক্সেকিউট হবে না, সেটা নির্ধারণ করে। এরা হলঃ if, else, switch, case, break, default

              2. লুপিং কিওয়র্ডঃ এরা হচ্ছে C এর পুনরাবৃত্তকরন বা reparation কিওয়র্ড। এরা C এর বিভিন্ন কোড সেগমেন্টকে নির্দিষ্ট শর্ত সাপেক্ষে বারবার এক্সেকিউট করতে সাহায্য করে। অর্থাৎ, এই কোডগুলো লুপ তৈরীতে সহায়তা করে থাকে। এরা হলঃ for, while, do, break, continue

              3. জাম্প কিওয়র্ডঃ এরা প্রোগ্রামের এক স্থান থেকে অন্য স্থানে প্রোগ্রাম এক্সেকিউশনের তাৎক্ষণিক স্থানান্তর ঘটায়। এই জন্যেই এদেরকে জাম্প কিওয়র্ড বলা হচ্ছে। এরা হলঃ return, goto


  • ডেটা টাইপ সম্পর্কিতঃ C ডেটা টাইপ সমূহ প্রয়োগ ও তাদের রূপান্তরকরণ সম্পর্কিত কাজ এই কিওয়র্ডগুলোর সহায়তায় সম্পন্ন হয়। এদেরকে ৬ টি উপশ্রেণী তে বিভক্ত করা হয়েছেঃ


              1. মৌলিক ডেটা টাইপ সমূহঃ C এর পূর্ব নির্ধারিত ৫ টি ডেটা টাইপ ব্যবহারের জন্য এই ৫ টি কিওয়র্ড ব্যবহার করা হয়। এরা হলঃ

char, int, float, double, void

              2. টাইপ লিমিট মডিফায়ার সমূহঃ এরা মৌলিক ডেটা টাইপ সমূহের ধারণক্ষমতায় কিছু পরিবর্তন আনে। এরা হচ্ছে,

short, long, signed, unsigned

              3. স্টোরেজ ক্লাস স্পেসিফায়ারঃ এরা বিভিন্ন ডেটা টাইপের ডেটা সম্বলিত ভ্যারিয়েবল সমূহ মেশিনের কোন ধরনের মেমরিতে জমা থাকবে সেই বিষয়ক নির্দেশনা দান করে। এদের ব্যবহার নিত্যনৈমিত্তিক না হলেও, দ্রুতগতির ও স্বল্প মেমরী ব্যবহারকারী প্রোগ্রাম তৈরীতে এদের ব্যবহার অপরিহার্য। এরা হলঃ

auto, extern, register, static

              4. এক্সেস মডিফায়ারঃ কোন ডেটার পরিবর্তন কিভাবে হবে বা আদৌ হবে কি না সেই সম্পর্কিত নির্দেশনা এরা দিয়ে থাকে। এদের ব্যবহারও মূলত অভিজ্ঞ প্রোগ্রামারদের হাতেই হয়ে থাকে। এরা হলঃ

const, volatile

              5. স্ট্রাকচার সম্পর্কিতঃ C ডেটা স্ট্রাকচার সম্পর্কিত কিওয়র্ড। এরা হলঃ

struct, union

              6. ইউজার ডিফাইন্ড ডেটা টাইপ সম্পর্কিতঃ এরা বিভিন্ন ইউজার ডিফাইন্ড ও এডভান্সড ডেটা টাইপ তৈরিকরণে সাহায্য করে। এরা হলঃ

typedef, enum


  • অপারেটঃ একটি মাত্র অপারেটর ই কিওয়র্ড হিসেবে বিদ্যমান। এটি কোন ডেটা টাইপ বা ভ্যারিয়েবল (যে কোন ধরণের) এর আকার বাইট (Byte) এককে হিসাব করে ব্যবহারকারী কে জানায়। এটি হলঃ


sizeof

সবগুলো কিওয়র্ডের আলাদা আলাদা সংক্ষিপ্ত কাজ ও ব্যবহার এর জন্য এখানে দেখতে পারেন।

তবে এদের পূর্ণাঙ্গ ব্যবহার কেবলমাত্র এদের নিয়মিত প্রয়োগের মাধ্যমেই শেখা সম্ভব, মুখস্থ করে নয়।

C এক্সপ্রেশন : Expression

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

C এক্সপ্রেশন সমূহও অনেকটা তেমনই। C ভাষায় এক্সপ্রেশন হচ্ছে অপারেটর ও অপার‍্যান্ড এর সমন্বয়ে তৈরী কোড সেগমেন্ট যার একটি নির্দিষ্ট চুড়ান্ত মান আছে। অর্থাৎ ঐ কোড সেগমেন্টকে এক্সেকিউট করলে, অপারেটর দের কাজ শেষ হবার পরে ১ টি মাত্র চুড়ান্ত মান পাওয়া যাবে। এই চুড়ান্ত মান গাণিতিক বা সংখ্যা মান হতে পারে, আবার যৌক্তিক বা লজিকার মান (সত্য বা মিথ্যা; True বা False) ও হতে পারে।

মোট কথা হল, এক্সপ্রেশন হচ্ছে এমন একটি কোড সমন্বয় যার একটি মান আছে। যেমন, ধরা যাক a, b ও c তিনটি ইন্টিজার ভ্যারিয়েবল। নিচের এসাইনমেন্ট স্টেটমেন্টটি খেয়াল করা যাক,

a= b+c;

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

এক্সপ্রেশন প্রায় সব সময়ই অপারেটর ও অপার‍্যান্ড (ভ্যারিয়েবল, কনস্ট্যান্ট ইত্যাদি) এর সমন্বয়ে গঠিত। এবং এক্সপ্রেশন এর সব সময়ই একটি লজিকাল বা যৌক্তিক মান থাকে। চুড়ান্ত মানের উপর ভিত্তি করে তার যৌক্তিক মান হয় সত্য অথবা মিথ্যা হয়।

C তে কোন বুলিয়ান (Boolean) True বা False নেই। কিন্তু অন্য একটি উপায়ে C তে সত্য বা মিথ্যা নিরূপন করা যায়। যখন কোন এক্সপ্রেশনের চুড়ান্ত সংখ্যা মান শূন্য (0) তখন সেই এক্সপ্রেশনটি মিথ্যা, অর্থাৎ লজিকাল মান হল False। যে কোন অশূন্য সংখ্যা মানের জন্য কোন এক্সপ্রেশন সত্য, অর্থাৎ লজিকালি True।
উল্টোভাবে বলতে গেলে, C ভাষায় সকল মিথ্যা এক্সপ্রেশন এর সংখ্যা মান 0 আর সত্য এক্সপ্রেশন এর মান অশূন্য (সাধারণত 1)।

মনে রাখতে হবে যে, অশূন্য মানের সকল এক্সপ্রেশন ই সত্য, তবে সাধারণত সত্য এক্সপ্রেশন এর মানকে  1 দ্বারা প্রকাশ করা হয়। এর মানে এই নয় যে, কেবল 1 ই সত্য বা True। বস্তুত কোন এক্সপ্রেশন এর মান শূন্য না হলেই তা সত্য।

এবার বলেন দেখি নিচের কোডের আউটপুট কত?

#include<stdio.h>

int main()
{
    int a, b, c, d;
    c=1;
    d=10;

    a= c>d;
    b= d<c;

    printf("%d %d", a, b);

return 0;
}

অপারেটর ও অপার‍্যান্ড এর উপর ভিত্তি করে এক্সপ্রেশন অনেক ধরনের হতে পারে। যেমন,

গাণিতিক বা Arithmetic অপারেটর কোন এক্সপ্রেশন এ থাকলে তাকে গাণিতিক বা arithmetic এক্সপ্রেশন বলে। আবার কোন গাণিতিক এক্সপ্রেশনে উপস্থিত অপার‍্যান্ড এর ধরন এর উপর ভিত্তি করে,
ইন্টিজার এক্সপ্রেশন,
ফ্লোটিং পয়েন্ট বা রিয়েল এক্সপ্রেশন
এবং মিশ্র বা মিক্সড এক্সপ্রেশন এই তিন ভাগে ভাগ করা যায়।

লজিকাল অপারেটর এর এক্সপ্রেশন হচ্ছে লজিকাল এক্সপ্রেশন আবার, কন্ডিশনাল অপারেটর সম্বলিত এক্সপ্রেশনকে কন্ডিশনাল এক্সপ্রেশন বলে।

এরকম আরো অনেক ধরনের এক্সপ্রেশন আছে।

C ভাষায় এক্সপ্রেশন খুব গুরুত্বপূর্ণ ভূমিকা পালন করে। কারণ C ভাষায় অনেক ধরনের অপারেটর আছে এবং বেশির ভাগ নির্দেশনাই এক্সপ্রেশন আকারে প্রকাশ করা হয়।

C এর শুরুটা কিভাবে ?


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


সংক্ষিপ্ত ইতিহাস


সব আধুনিক প্রোগ্রামিং ভাষাগুলির মূল ALGOL।  এটা ১৯৬০ সাল এ তৈরি।  ALGOL প্রথম স্ট্রাকচার প্রোগ্রামিং এর ধারণা দেয়।

১৯৬৭ এর দিকে মার্টিন রিচার্ডস BCPL (Basic Combined Programming Language) তৈরি করেন। ১৯৭০ সালে, যুক্তরাষ্ট্রের বেল গবেষণাগারে বিজ্ঞানী কেন টমসন তৈরি করেন B নামক একটি প্রোগ্রামিং ভাষা। এটি ছিল পূর্বের BCPL-এর একটি উন্নত সংস্করণ। B দিয়েই UNIX অপারেটিং সিস্টেম প্রথমে তৈরি হয়েছিল বেল গবেষণাগারে। BCPL এবং B উভয়েই টাইপবিহীন একটি প্রোগ্রামিং ভাষা ছিল।

১৯৭২ সালে, ডেনিস রিচি বেল গবেষণাগারে  ALGOL, B এবং BCPL অনুসরণ করেন এবং নিজে থেকে আরো কিছু কৌশল ব্যবহার করে তৈরি করেন "সি" (C) ল্যাঙ্গুয়েজ। মূলত B-এর সীমাবদ্ধতা গুলো দূর করার উদ্দেশ্যেই "সি" এর উৎপত্তি। এর পর UNIX অপারেটিং সিস্টেমকে C দ্বারা ডেভেলপ করা হয়। UNIX আজকের সর্বাধিক জনপ্রিয় নেটওয়ার্ক অপারেটিং সিস্টেম।

৭০ এবং ৮০ দশকের দিকে C এর জনপ্রিয়তা বাড়ার সাথে সাথে এর অনেকগুলো ভার্সন তৈরি হয়। ১৯৮৩ সালে আমেরিকান মাননিয়ন্ত্রক সংস্থা (American National Standards Institute ; সংক্ষেপে ANSI) C এর ১টি আদর্শ ভার্সন তৈরির জন্য কমিটি গঠন করে। দীর্ঘ ৬ বছর পরে ১৯৮৯ সালে সেই আদর্শ সি ভাষাটি তৈরি হয়, যা আমেরিকান মাননিয়ন্ত্রক সংস্থা C (আনসি সি (ANSI C)) নামে পরিচিত। পরবর্তিতে আন্তর্জাতিক মাননিয়ন্ত্রক সংস্থা (ISO) ১৯৯০ সালে C এর এই আদর্শ ভার্সনটি গ্রহণ করে, যা C90 নামে পরিচিত। মুলত "C89" এবং "C90" একই ভাষা। যুগের প্রয়োজনে আন্তর্জাতিক মাননিয়ন্ত্রক সংস্থা ১৯৯৫ সালে এই সংস্করণকে বর্ধিত করে এবং পরবর্তিতে ১৯৯৯ সালে সম্পূর্ণ নতুন একটি সংস্করণ প্রকাশ করে যা C99 নামে পরিচিত। সর্বশেষ ২০১১ সালে সি প্রোগ্রামিং ল্যাঙ্গুয়েজের নবীনতম সংস্করণ C11 প্রকাশিত হয়।




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



প্রোগ্রামিং দক্ষতা


প্রোগ্রামিং দক্ষতা বৃদ্ধি করতে C অতুলনীয় একটি প্রোগ্রামিং ভাষা। তারমানে এই নয় যে C ভাষা শিখলেই তুমি প্রোগ্রামিং এ দক্ষ হয়ে যাবে।


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

বাংলা ভাষা ব্যবহার করতে পারলেই যেমন, তা দিয়ে সাহিত্য রচনা করা যায় না ঠিক তেমনি, কোন প্রোগ্রামিং ল্যাংগুয়েজ এর নিয়মকানুন (syntax) মুখস্ত, কণ্ঠস্থ বা ঠোটস্থ করলেই তুমি খুব ভালো ভালো প্রোগ্রামার হয়ে যাবে ব্যাপারটা তা নয়। প্রোগ্রামার হতে গেলে তোমাদের নিয়মকানুন গুলোকে বিভিন্ন ক্ষেত্রে সৃজনশীল উপায়ে কিভাবে ব্যবহার করা যায়, সেটা নিয়ে ভাবতে হবে।



বেসিক উপাদান


C এর বেসিক উপাদান গুলো প্রায় সকল প্রোগ্রামিং ভাষাকেই  কভার করে। সব প্রোগ্রামিং ল্যাঙ্গুয়েজ এই ভ্যারিয়েবল, if-else, loop, swich case, function, array ইত্যাদি এর ধারণা আছে। আর এই সব কিছুর ধারণা C থেকে নিবো আমরা। আর এই ধারণা আমরা একবার পেয়ে গেলে আমাদের নতুন প্রোগ্রামিং ভাষা শিখতে বেশি কষ্ট হবেনা।



C দিয়ে তৈরি কিছু জনপ্রিয় সফটওয়্যার -

 

  • ওরাকল - এটা ডাটাবেজ সফটওয়্যার
  • এন্ড্রয়েড এর কোর লাইব্রেরি সি দিয়ে লেখা
  • MySQL - এটাও একটা ডাটাবেজ সফটওয়্যার
  • প্রায় সকল ডিভাইস ড্রাইভার সি দিয়ে লেখা
  • প্রতিটা ওয়েব ব্রাউজার এর প্রধান অংশ সি দিয়ে লেখা
  • Unix অপারেটিং সিস্টেম ডেভেলপ হয়েছে সি দিয়ে


সি ভাষায় সফটওয়্যার কিভাবে তৈরি হয় ?


আমাদের সবাই জানি যে .exe ফাইল একটি সফটওয়্যার। মনে করো, এখন আমরা একটা সফটওয়্যার বানাব যার নাম calculator.exe । এখন বিষয়টা হলো .exe ফাইল আমরা বানাবো কিভাবে, .exe  ফাইল অনেক গুলো ০ আর ১ এর সমাবেশ। আর ০,১ মেশিন ভাষা, আর এই ভাষায় কোড করা অনেক কঠিন এবং কোড লিখতেও অনেক কষ্ট হয়। আচ্ছা ধরো আমরা .exe ফাইল বানিয়েও ফেললাম কিন্তু .exe তো অপারেটিং সিস্টেম ডিপেন্ডেন্ট যেটা অন্য কোনো অপারেটিং সিস্টেম এর জন্য উপযোগি না। তাহলে কি করতে হবে অন্য অপারেটিং সিস্টেম এর জন্য আমাদের আবার নতুন করে কোড লিখতে হবে ঐ অপারেটিং সিস্টেম এর ফরমেট অনুযায়ী। তাহলে ভাব তোমাকে কত কষ্ট করতে হবে ?

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

আচ্ছা তাহলে আমরা .c ফাইল কেন বানালাম ?


কারণ C ল্যাঙ্গুয়েজ হার্ডওয়্যার ইন্ডিপেন্ডেন্ট  এবং এতে প্রোগ্রাম তৈরি করা ও সহজ। ধরো আমাদের দুইটা নম্বর অ্যাড এর একটি প্রোগ্রাম বানাতে হবে তাহলে (২ + ৩) লিখলেই হয়ে গেল (এইটা আমরা প্রোগ্রাম করার সময় ভালো মতো বুজবো) কিন্তু আমাদের যদি .exe ফাইল এ কোডিং করতে হয় তাহলে ওখানে ০ এবং ১ এর কিছু কোডিং করতে হতো আর সেটা আমাদের জন্য সুবিধাজনক না।  এখন ধরো আমরা একটা ক্যালকুলেটর এর প্রোগ্রাম লিখে ফেলেছি এবং সোর্স কোডটি  calculator.c নাম এর ফাইল এ আছে।

এখন আমাদের দরকার .c ফাইলকে সফটওয়্যার এ কনভার্ট করা কারণ .c ফাইল সফটওয়্যার না। এই কাজটা করার জন্য সবচেয়ে প্রথমে যেটা দরকার সেটা হলো প্রিপ্রসেসর সফটওয়্যার।

প্রিপ্রসেসর সফটওয়্যার কি করে বা এর কাজ কি ?


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

আমাদের প্রোগ্রাম তৈরির সময় অনেক গুলো হেডার ফাইল অ্যাড করতে হয় যে গুলো আমাদের তৈরি না। কিন্তু এই ফাইল এর ভিতরের কোড গুলো আমাদের কোড এর সাথে অ্যাড করা গুরুত্বপূর্ণ।  আমরা কোড এর মধ্যে এমন কিছু লাইন লিখি যার কারণে প্রিপ্রসেসর হেডার ফাইল এর কনটেন্ট গুলো কে আমাদের ফাইল এর কনটেন্ট এর সাথে মিশিয়ে একটা নতুন ফাইল তৈরি করে। যার এক্সটেনশন .i তার মানে calculator.c এই ফিলকে প্রিপ্রসেসর এ কনভার্ট করলে calculator.i  নাম একটি ফাইল তৈরি হবে। এই নতুন ফাইলটা আমাদের ফাইল এর মতোই শুধু "#" দ্বারা শুরু ওই সকল স্টেটমেন্ট গুলোর পরিবর্তে কিছু অন্য স্টেটমেন্ট অ্যাড হয়েছে যেই স্টেটমেন্ট গুল ঐ হেডার ফাইল এর মধ্যে ছিল।

সাধারণত, প্রিপ্রসেসর "#" দিয়ে শুরু সকল স্টেটমেন্ট হ্যান্ডেল করে। আর সবচেয়ে জনপ্রিয় স্টেটমেন্ট হলো #include, যেমন আমরা প্রতিটা প্রোগ্রাম এ #include<stdio.h> এই স্টেটমেন্টটা আমরা লিখি, এইটা একধরণের কম্যান্ড যার মানে হেডার ফাইল stdio.h এর মধ্যে যেই কনটেন্ট গুল আছে তা প্রোগ্রাম এর সাথে যুক্ত হয়ে যাও।

প্রিপ্রসেসর এর মাধ্যমে calculator.i নামে যেই ফাইলটা তৈরি হয়েছে সেইটা এখন কম্পাইলার সফটওয়্যার এর মাধ্যমে ট্রান্সলেট করতে হবে।  কম্পাইলার ওই প্রোগ্রাম ফাইলকে ট্রান্সলেট করে একটা ফাইল তৈরি করে যেটাকে বলা হয় অবজেক্ট (calculator.obj/calculator.o) ফাইল।

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

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

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

লাইব্রেরি ফাইল এর কোড এবং অবজেক্ট ফাইল এর কোড লিংক করার জন্য লিংকার সফটওয়্যার ব্যবহার হয়। লিংকার অবজেক্ট ফাইল এন্ড লাইব্রেরি এর কানেক্ট করে একটা নতুন ফাইল তৈরি করে আর সেটাই হলো .exe ফাইল। যেই ফাইল এর অপেক্ষায় আমরা ছিলাম কি তাইতো ? তাহলে সর্বশেষ যে ফাইলটি আমরা পাব তা calculator.exe ফাইল। এই .exe ফাইলটাই আমাদের সফটওয়্যার।






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

এখন বলো তুমি যদি তোমার তৈরি করা একটা সফটওয়্যার তোমার বন্ধুকে দিতে চাও তাহলে তুমি কোন ফাইল দিবা ?