সি প্রোগ্রামিং বিট ফিল্ড | C bit field
এই অধ্যায়ে আপনি সি প্রোগ্রামে বিট ফিল্ডের ব্যবহার শিখবেন। বিট ফিল্ড ব্যবহার করে মেমোরির সদ্ব্যবহার করা যায়।
ধরুন, আপনার প্রোগ্রামে কিছু TRUE/FALSE ভ্যারিয়েবল রয়েছে যেগুলোকে structure ভ্যারিয়েবলের মাধ্যমে শ্রেণীবদ্ধ করা হয়েছে এবং এই স্ট্রাকচার ভ্যারিয়েবলের নাম status রাখা হয়েছে। উদাহরণস্বরুপঃ
struct {
unsigned int widthValidated;
unsigned int heightValidated;
} status;
এই স্ট্রাকচার ভ্যারিয়েবলের জন্য মেমোরিতে ৮ বাইট জায়গা/স্পেসের প্রয়োজন হবে। কিন্তু আমরা প্রত্যেক ভ্যারিয়েবলের জন্য হয় 0 অথবা 1 স্টোর করতে যাচ্ছি। এ ধরনের পরিস্থিতিতে মেমোরির সঠিক ব্যবহারের জন্য সি প্রোগ্রামিং ল্যাংগুয়েজ উত্তম পন্থা সরবরাহ করে।
আপনি যদি স্ট্রাকচারের মধ্যে এধরণের ভ্যারিয়েবল ব্যবহার করে থাকেন তাহলে আপনি এই ভ্যারিয়েবল-সমূহের মেমোরি সাইজ বা বাইট-সংখ্যাও নির্ধারণ করে দিতে পারেন যা কম্পাইলারকে আগাম বার্তা দিবে যে, আপনি এই ভ্যারিয়েবল-সমূহের জন্য শুধুমাত্র ঐ সংখ্যক বাইট ব্যবহার করতে যাচ্ছেন। উদারণস্বরুপঃ উপরের স্ট্রাকচারকে নিম্মের ন্যায়ও লেখা যেতে পারেঃ
struct {
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status;
উপরের স্ট্রাকচার ভ্যারিয়েবলটি মেমোরিতে ৪(চার) বাইট জায়গা দখল করবে, কিন্তু ভ্যালু স্টোর করার জন্য শুধুমাত্র ২ বাইট জায়গা লাগবে।
আপনি যদি ৩২টি পর্যন্ত ভ্যারিয়েবল ব্যবহার করে থাকেন এবং প্রত্যেকের সাইজ যদি ১ বিট করে হয় তবুও স্ট্রাকচার ভ্যারিয়েবল status মেমোরিতে ৪(চার) বাইট জায়গা দখল করবে। যাইহোক, ভ্যারিয়েবলের সংখ্যা ৩৩ হওয়া মাত্র ইহা পরবর্তী মেমোরি স্লট বরাদ্দ করবে যা ৮ বাইট মেমোরি ব্যবহার করা শুরু করবে। চলুন নিচের উদাহরণের মাধ্যমে আরো স্বচ্ছ ধারণা নিইঃ
#include <stdio.h>
#include <string.h>
/* সাধারণ স্ট্রাকচার ডিফাইন্ড */
struct {
unsigned int widthValidated;
unsigned int heightValidated;
} status1;
/* বিট ফিল্ডসহ স্ট্রাকচার ডিফাইন্ড।*/
struct {
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status2;
int main( ) {
printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
printf( "Memory size occupied by status2 : %d\n", sizeof(status2));
return 0;
}
উপরের প্রোগ্রামটি কম্পাইল এবং এক্সিকিউট করা হলে নিচের ন্যায় ফলাফল দেখাবেঃ
Memory size occupied by status1 : 8 Memory size occupied by status2 : 4
বিট ফিল্ড ডিক্লারেশন
স্ট্রাকচারের মধ্যে বিট ফিল্ডকে নিম্নের ন্যায় ডিক্লেয়ার করা হয়ঃ
struct {
type member_name : size ;
};
নিম্নে বিট ফিল্ডের এলিমেন্ট-সমূহকে বর্ণনা করা হলোঃ
- type: হলো বিট ফিল্ড ভ্যারিয়েবলের টাইপ। টাইপ সাধারণত
int
,signed
অথবাunsigned int
হতে পারে। - member_name বিট ফিল্ড ভ্যারিয়েবলের নাম
- size বিট ফিল্ড ভ্যারিয়েবলের বিটের সংখ্যা। নির্ধারিত টাইপের বিট সাইজ থেকে এই সাইজ অবশ্যই ছোট হতে হবে।
পূর্ব নির্ধারিত সাইজ ব্যবহার করে ভ্যারিয়েবল ডিফাইন্ড করাকে বিট ফিল্ড বলা হয়। একটি বিল্ট ফিল্ড একের অধিক বিট ধারন করতে পারে।
উদাহরণস্বরুপ, আপনার যদি এমন একটি ভ্যারিয়েবলের প্রয়োজন হয় যা 0 থেকে 7 পর্যন্ত ভ্যালু স্টোর করতে পারে তাহলে আপনি নিম্নের ন্যায় ৩বিটের একটি বিট ফিল্ড ভ্যারিয়েবল ডিফাইন করতে পারেনঃ
struct {
unsigned int age : 3;
} Student;
উপরের প্রোগ্রামটি সি কম্পাইলারকে এই নির্দেশনা দেয় যে age ভ্যারিয়েবল তার ভ্যালু স্টোর করার জন্য ৩ বিট ব্যবহার করতে চলেছে। কিন্তু আপনি যদি ৩ বিটের চেয়ে বেশি ব্যবহার করতে চান তাহলে ইহা আপনাকে এই কাজের জন্য সম্মতি দিবে না। চলুন নিচের উদাহরণের সাহায্যে প্রয়োগ দেখে নিইঃ
#include <stdio.h>
#include <string.h>
struct {
unsigned int age : 3;
} Student;
int main( ) {
Student.age = 4;
printf( "Sizeof( Student ) : %d\n", sizeof(Student) );
printf( "Student.age : %d\n", Student.age );
Student.age = 7;
printf( "Student.age : %d\n", Student.age );
Student.age = 8;
printf( "Student.age : %d\n", Student.age );
return 0;
}
উপরের প্রোগ্রামটিকে যখন কম্পাইল করা হবে তখন ইহা একটি সতর্কবার্তার সহিত কম্পাইল হবে এবং এক্সিকিউশন সম্পন্ন হলে নিচের ন্যায় ফলাফল দেখাবেঃ
Sizeof( Student ) : 4 Student.age : 4 Student.age : 7 Student.age : 0