সূচিপত্র

তোমাকে যদি বলা হত একজন সেলেব্রিটির প্রিয় খাবার, মুভি, খেলা, খেলোয়াড় এবং ব্যক্তিত্বের নাম ইনপুট নিয়ে জমা রাখতে হবে, তুমি কী করতা? তুমি হয়তো fav_food[20], fav_movie[20], fav_sports[20], fav_player[20], fav_personality[20] এরকম পাঁচটি স্ট্রিং (ক্যারেক্টার অ্যারে) ডিক্লেয়ার করতা। কিন্তু এখন যদি বলা হয় দুইজন সেলেব্রিটির ডাটা নিতে হবে, তাহলে কী fav_food_1, fav_food_2… এভাবে ভ্যারিয়েবল ডিক্লেয়ার করতা? যদি ১০০ জন সেলেব্রিটির ডাটা কালেক্ট করতে বলে? বুঝাই যাচ্ছে, এভাবে কোড লেখাটা বেশ ইনএফিসিয়েন্ট। 

তো এই ক্ষেত্রে একটা সমাধান হতে পারে অ্যারে ব্যবহার করা। আমরা food[100][20], movie[100][20] এরকম পাঁচটি অ্যারে ব্যবহার করে কোডটা লিখতে পারি। তবে এর চেয়েও ভাল একটি সমাধান আছে এবং সেটি হল ডাটা স্ট্রাকচার! এটি হল নতুন এক ধরণের ডাটা টাইপ যেটা তুমি নিজে ডিফাইন করে দিবা। আবার তোমার ডিফাইন করা এই ডাটা টাইপ হবে কিছু প্রিডিফাইনড ডাটা টাইপের সমষ্টি! তো কথা না বাড়িয়ে কাজ শুরু করে দেওয়া যাক এই স্ট্রাকচার নিয়ে।

আমাদেরকে প্রথমেই শিখতে হবে কীভাবে একটি স্ট্রাকচার ডিফাইন করতে হয়

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

তো, এই struct স্টেটমেন্টের ফরম্যাটটা হল নিচের মতঃ

struct structure_tag
{
   member definition;
   member definition;
   ...
   member definition;
} one_or_more_structure_variables;

(1) structure_tag-এর ব্যাপারটা অপশনাল। এটি রাখা হয়, যাতে তুমি এই ট্যাগ ব্যবহার করে পরে এই টাইপের আরও ভ্যারিয়েবল ডিক্লেয়ার করতে পার সেকেন্ড ব্র্যাকেটের ভেতরের ডেফিনিশন গুলো না দিয়েই।

(2) member definition গুলো হল, তোমাকে প্রথমত বলে দিতে হবে এই মেম্বারগুলো কী টাইপের (float, double, int ইত্যাদি) এবং দ্বিতীয়ত এর একটি নামও দিতে হবে।

(3) এবং সবশেষে সেমিকোলনের আগে এক বা একাধিক ভ্যারিয়েবল তুমি ডিক্লেয়ার করতে পার, তবে এই ব্যাপারটিও অপশনাল।

এখানে ১ আর ৩ দুইটি ব্যাপারকে অপশনাল বলা হয়েছে। এর মানে এই না যে, তুই দুইটা জিনিসই বাদ দিতে পারবা, এদের মধ্যে যেকোনো একটি অবশ্যই থাকবে। তবে দুইটিই থাকতে হবে এমন কোনো কথা নেই।

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

struct CelebrityInfo {
    char movie[20];
    char sports[20];
    char player[20];
    char personality[20];
    char food[20];
} number1, number 2;

ব্যস হয়ে গেল। আমরা চাইলে এটা লিখতে পারতাম এভাবেঃ

struct CelebrityInfo {
    char movie[20];
    char sports[20];
    char player[20];
    char personality[20];
    char food[20];
} number 1;
struct CelebrityInfo number2;

অর্থাৎ আমরা ট্যাগ রাখার কারণে পরবর্তীতে এটি ব্যবহার করে এধরনের আরও ভ্যারিয়েবল ডিক্লেয়ার করতে পারছি। অথবা আমরা এভাবেও কাজটি করতে পারতামঃ

struct {
    char movie[20];
    char sports[20];
    char player[20];
    char personality[20];
    char food[20];
} number1, number2;

কিন্তু এক্ষেত্রে আমরা পরবর্তীতে আর এধরণের নতুন কোনো ভ্যারিয়েবল ডিক্লেয়ার করতে পারতাম না। কারণ আমরা ট্যাগ রাখিনি।

/* আশা করি স্ট্রাকচার ডিফাইন করা পর্যন্ত বুঝতে পেরেছ। না বুঝলে এই অংশ পর্যন্ত আবার পড়, এরপরও না বুঝলে কমেন্টে জানাও। */

এবার আমরা দেখবো স্ট্রাকচারের মেম্বার গুলোকে কীভাবে এক্সেস করা যায়  

ডাটা স্ট্রাকচারের মেম্বারগুলোকে এক্সেস করার জন্য আমরা বিশেষ একটা অপারেটর দেখবো। এটি হল ডট অপারেটর। যেমন আমরা যদি number1-এর প্রিয় প্লেয়ার এক্সেস করতে চাই, তাহলে লিখবো number1.player

আমরা ফাংশনের আর্গুমেন্ট হিসেবে অ্যারে পাঠানোর সময় যেমন প্র্যারানথেসিস ব্যবহার করি না, এক্ষেত্রেও করবো না। তবে যদি কোনো কারণে প্রিয় প্লেয়ারের নামের দ্বিতীয় অক্ষর জানতে হয়, তবে লিখবো number1.player[1] 😀

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

#include <stdio.h>
int main() {
    struct {
        char movie[20];
        char sports[20];
        char player[20];
        char personality[20];
        char food[20];
    } number1, number2;
    printf("Input for celebrity 1: \n");
    scanf("%s", number1.food);
    scanf("%s", number1.movie);
    scanf("%s", number1.sports);
    scanf("%s", number1.player);
    scanf("%s", number1.personality);
    printf("Input for celebtrity 2: \n");
    scanf("%s", number2.food);
    scanf("%s", number2.movie);
    scanf("%s", number2.sports);
    scanf("%s", number2.player);
    scanf("%s", number2.personality);
    printf("\n\n");
    printf("Category\t\tCelebrity 1\t\tCelebrity 2\n");
    printf("Favourite Food       \t\t%s\t\t%s\n", number1.food, number2.food);
    printf("Favourite Movie      \t\t%s\t\t%s\n", number1.movie, number2.movie);
    printf("Favourite Sports     \t\t%s\t\t%s\n", number1.sports, number2.sports);
    printf("Favourite Player     \t\t%s\t\t%s\n", number1.player, number2.player);
    printf("Favourite Personality\t\t%s\t\t%s\n", number1.personality, number2.personality);
    printf("Kaj shes, ebar ghumao.\n");
    return 0;
}

এই কোড রান করে ইনপুট দিলে খুব সুন্দর নিচের মত আউটপুট দেখা যাবেঃ

Snap 2015-07-09 at 16.21.18

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

হিন্টসঃ gets() ব্যবহার করতে পার।

তো আমরা দুইজন সেলেব্রিটির জন্য সমস্যাটা সমাধান করে ফেললাম। আমাদেরকে ১০০ জনের জন্য করতে দিলে আমরা আঁটকে যেতাম! তবে একটু খেয়াল করলেই বুঝতে পারবে, আমরা এখানে একই কাজ বারবার করেছি। নাম্বার ১-এর জন্য যেই কাজ, ২-এর জন্যও একই কাজ। সেটা বারবার না করে আমরা অ্যারের মাধ্যমেও করতে পারতাম! এবার চল অ্যারের মাধ্যমে কোডটা লিখে ফেলা যাক! 🙂

#include <stdio.h>
int main() {
    struct celebrite{
        char movie[20];
        char sports[20];
        char player[20];
        char personality[20];
        char food[20];
    } celebrities[100]; // array declare kore dilam :D
    int i;
    for (i=0; i<2; i++) {
        printf("Input for celebrity #%d\n", i+1);
        scanf("%s", celebrities[i].food);
        scanf("%s", celebrities[i].movie);
        scanf("%s", celebrities[i].sports);
        scanf("%s", celebrities[i].player);
        scanf("%s", celebrities[i].personality);
    }
    printf("\n\n");
    for (i=0;i<2;i++) {
        printf("Output for celebrity #%d\n", i+1);
        printf("Favourite Food : %s\n", celebrities[i].food);
        printf("Favourite Movie : %s\n", celebrities[i].movie);
        printf("Favourite Sports : %s\n", celebrities[i].sports);
        printf("Favourite Player : %s\n", celebrities[i].player);
        printf("Favourite Personality : %s\n", celebrities[i].personality);
    }

    return 0;
}

এই কোডেও আগের মত একই সমস্যা। এফিসিয়েন্ট কর! 😀

আজকের মত এখানেই শেষ। সবাই ভাল থাকবে, সুস্থ থাকবে। 🙂

Muntasir Wahed

Muntasir Wahed

System Administrator at স্বশিক্ষা.com
Jack of all trades, master of none.
Muntasir Wahed
Muntasir Wahed