در ++C ما گزینه های مختلفی برای نگه داری داده ها داریم. مانند کلاس های stack ، set ، map ، bitset ، vector . فقط کافی است نوع داده خود را مشخص کنید و سپس آن یکی را که مناسب کار شما است انتخاب کنید و یا حتی در صورت لزوم با استفاده از قابلیت ارث بری آن را گسترش بدهید؛ شاید هم بخواهید نوع داده انتزاعی خود را برای نگه داری داده های تان به وجود بیاورید. در هر حال به شما پیشنهاد می کنم مطالب قبلی ما را در درباره داده ساختار ها بخوانید و مطالب آینده را پیگیری کنید!
در این مطلب سعی شده است که کلاس
bitset
و ویژگی ها و استفاده هایش بررسی شود و چند مثال از آن ها را ببینیم.
مجموعه بیتی برای نگه داری بیت هاست (۰ و ۱). شاید در همین ابتدا به من بگویید من که می دانم چطور یک آرایه اعداد صحیح یا کاراکتر تعریف کنم و تعدادی صفر و یک را در آن جا دهم! اما باید بدانید که کلاس
bitset
برای استفاده از کمترین مقدار حافظه بهینه سازی شده است و در واقع روش کار آن به این صورت است که آرایه ای از نوع داده boolean را فقط یک بیت حافظه برای ذخیره سازی نیاز دارد، ایجاد می کند. فرض کنیم می خواهیم آرایه ای از بیت ها را به طول چهار ذخیره کنیم؛ با آرایه ای از اعداد صحیح ما (۸*۴)*۴ بیت ، با آرایه ای از کاراکتر ها ۸*۴ بیت و با کلاس
bitset
فقط ۴ بیت برای ذخیره سازی آرایه مان نیاز داریم! اما این همه اش نیست! مزیت دیگر استفاده ار مجموعه بیتی، method های تعریف شده در این کلاس است که کار با اعداد دودویی را بسیار راحت می کند. برای مثال تبدیل اعداد دهدهی به دودویی و برعکس، ایجاد مقدار هش شده از عدد دودویی، چاپ یکباره کل آرایه روی خروجی، به دست آوردن تعداد یک های موجود در آرایه و … تنها با یک فراخوانی انجام می شود!
<bitset>
را وارد کرده باشید و توجه کنید که نام کلاس
bitset
در فضای نام
std
قرار دارد.
کار را با تعریف یک مجموعه بیتی آغاز می کنیم! برای تعریف، لازم است که تعداد بیت هایی که می خواهیم این شئ در خود نگه دارد را داشته باشیم (که اینجا برای مثال، ۸ بیت در نظر گرفته شده است).
bitset<8> bitArray;
حالا بیایید روش های مقدار دهی را ببینیم. ابتدا مفدار دهی با استفاده از تابع سازنده:
(در تمام حالت های زیر مجموعه بیتی تعریف شده را با مقدار دودویی ۱۱۱۱۱۱۱۱ معادل ۲۵۵ دهدهی، مقدار دهی کرده ایم.)
bitset<8> bitsArray1(255); // 11111111 bitset<8> bitsArray2(0xff); // 11111111 bitset<8> bitsArray3(string("11111111")); // 11111111 char C_string[9] = { '1', '1', '1', '1', '1', '1', '1', '1' , ' ' }; bitset<8> bitsArray4(C_string); // 11111111 bitset<8> temp(255); bitset<8> bitsArray5(temp); // 11111111
همانطور که می بینید در چهار حالت از تابع سازنده برای مقداردهی استفاده کرده ایم؛ مقداردهی با عدد دهدهی، با عدد شانزده شانردهی، با رشته زبان سی پلاس پلاس، با رشته زبان سی و با یک محموعه بیتی هم اندازه که مقدار دهی شده، انجام شده است. هنگام مقداردهی این مجموعه با اعداد غیر دودویی، معادل دودویی آن به اندازه تعریف شده برای مجموعه، از بیت کم ارزش به بعد در آن ذخیره می شود(پس بهتر است مطمئن باشید اندازه ای که تعریف کردید بیشتر یا مساوی اندازه بیت های مقدار داده شده در مبنای دو است).
حالا مقدار دهی بعد از تعریف کردن یک شئ از مجموعه بیتی:
bitset<8> bitsArray1; bitsArray1 = 255; // 11111111 bitset<8> bitsArray2; bitsArray2 = 0xff; // 11111111 bitset<8> bitsArray3; bitsArray3 = bitset<8>(string("11111111")); // 11111111 bitset<8> bitsArray4; char C_string[9] = { '1', '1', '1', '1', '1', '1', '1', '1', ' ' }; bitsArray4 = bitset<8>(C_string); // 11111111 bitset<8> bitsArray5; bitset<8> temp(255); bitsArray5 = temp;
عملگر = که در سی پلاس پلاس کار انتساب را انجام می دهد برای انتساب اعداد دهدهی،اعداد شانزده شانزدهی و مجموعه بیتی به یک مجموعه بیتی سربارگذاری (overload) شده است. بنابراین شما می توانید یک عدد دهدهی یا شانزده شانزدهی را به صورت مستقیم به یک مجموعه بیتی منتسب کنید و مقدار دودویی آن عدد در مجموعه بیتی جای می گیرد. اما درباره انتساب یک مجموعه بیتی به یک مجموعه بیتی شما می توانید یک شئ از قبل تعریف شده یا یک شئ موقت را در سمت راست عملگر انتساب قرار دهید البته باید توجه کنید که آن شئ اندازه ای برابر با با شئ سمت چپ داشته باشد وگرنه از کامپایلر خطا دریافت می کنید. تغییر مقدار یک مجموعه بیتی مشابه حالت های مقدار دهی بعد از تعریف انجام می شود.
عملگر های بیتی هم برای مجموعه های بیتی سربارگذاری شده است؛ که این می تواند بسیار پر استفاده باشد.
عملگر [] آخرین عملگر مورد بحثی است که برای کلاس
bitset
سربارگذاری شده است. عملکرد آن هم مثل کاری است که در آرایه ها انجام می دهد؛ یعنی دسترسی به یک عضو از مجموعه!
فعلاً مطلب را با بررسی چند method از کلاس
bitset
و یک نکته تمام می کنیم اما امیدوارم با کمک نظرات و سوال های شما، در روز های آینده مثال و توضیح های بیشتری به این مطلب مفید اضافه کنیم.
()bitset::count
یک عدد صحیح به عنوان تعداد بیت های سِت شده (برابر با ۱) را بر می گرداند.
()bitset::size
یک عدد ضحیح به عنوان اندازه مجموعه بیتی را که در هنگام تعریف آن را مشخص کرده اید، بر می گرداند.
(bitset::test(i
یک مقدار boolean به عنوان ارزش عنصر شماره i را بر می گرداند (
true
اگر ۱ باشد و
false
اگر ۰ باشد).
()bitset::any
یک مقدار boolean بر می گرداند که اگر
true
باشد یعنی حداقل یک بیتِ سِت شده (برابر با ۱) در مجموعه وجود دارد و اگر
false
باشد یعنی تمام بیت ها ۰ هستند.
()bitset::none
عملکردی متضاد با
()any
دارد. در صورتی که مقدار خروجی آن
true
باشد یعنی هیچ کدام از بیت های مجموعه ۱ نیستند و اگر
false
باشد یعنی حداقل یک بیتِ ست شده وجود دارد.
()bitset::all
این method در ۱۱++C اضافه شده است و با فراخوانی آن، بررسی می کند که آیا تمام بیت های مجموعه سِت شده اند یا نه و به ترتیب مقادیر
true
و
false
می تواند خروجی این فراخوانی باشد.
در کامپایلری که ۱۱++C را پشتیبانی می کند به راحتی با دستور
()bitsArray.to_string
و یا در ۹۸++C با دستور
bitsArray.to_string<char, string::traits_type, string::allocator_type>();
می توانید یک رشته تحویل بگیرید که حاوی بیت های مجموعه بیتی مثالی ما یعنی
bitsArray
است. بیت ها هم به همان ترتیبی در رشته قرار می گیرند که در یک جریان خروجی با عملگر
>>
، قرار می گیرند.
()bitset::to_ulong
یک مقدار
unsigned long int
(عدد صحیح بزرگ بدون علامت) بر می گرداند. اگر مقدار دهدهی معادل مجموعه بیتی از ظرفیت
unsigned long int
بیشتر باشد، یک Exception رخ می دهد.
()bitset::to_ullong
در ۱۱++C اضافه شده است و یک مقدار
unsigned long long int
(عدد صحیح بسیار بزرگ بدون علامت) بر می گرداند.
نکته پایانی:
همانطور که دیدید کلاس
bitset
، پویا نیست؛ به این معنی که اندازه شئ ای که می خواهید بسازید را باید در هنگام تعریف به صورت مشخص بدانید تا حافظه لازم برای آن در شروع اجرای برنامه تخصیص داده شود و در ادامه هم نمی تواند تغییر کند. اگر به یک مجموعه بیتی پویا نیاز دارید باید بگویم متاسفانه در کتابخانه استاندارد ++C آن را نداریم اما به لطف کتابخانه های Boost برای ++C می توانید مجموعه بیتی پویا داشته باشید! به اینجا سری بزنید!