منبع اصلی نوشتار زیر در این لینک قرار دارد

مجموعه بیتی (bitset) در ++C

در ++C ما گزینه های مختلفی برای نگه داری داده ها داریم. مانند کلاس های stack ، set ، map ، bitset ، vector . فقط کافی است نوع داده خود را مشخص کنید و سپس آن یکی را که مناسب کار شما است انتخاب کنید و یا حتی در صورت لزوم با استفاده از قابلیت ارث بری آن را گسترش بدهید؛ شاید هم بخواهید نوع داده انتزاعی خود را برای نگه داری داده های تان به وجود بیاورید. در هر حال به شما پیشنهاد می کنم مطالب قبلی ما را در درباره داده ساختار ها بخوانید و مطالب آینده را پیگیری کنید!

در این مطلب سعی شده است که کلاس

bitset

 و ویژگی ها و استفاده هایش بررسی شود و چند مثال از آن ها را ببینیم.

bit 0 1

مجموعه بیتی برای نگه داری بیت هاست (۰ و ۱). شاید در همین ابتدا به من بگویید من که می دانم چطور یک آرایه اعداد صحیح یا کاراکتر تعریف کنم و تعدادی صفر و یک را در آن جا دهم! اما باید بدانید که کلاس

bitset

  برای استفاده از کمترین مقدار حافظه بهینه سازی شده است و در واقع روش کار آن به این صورت است که آرایه ای از نوع داده boolean را فقط یک بیت حافظه برای ذخیره سازی نیاز دارد، ایجاد می کند. فرض کنیم می خواهیم آرایه ای از بیت ها را به طول چهار ذخیره کنیم؛ با آرایه ای از اعداد صحیح ما (۸*۴)*۴ بیت ، با آرایه ای از کاراکتر ها ۸*۴ بیت و با کلاس

bitset

 فقط ۴ بیت برای ذخیره سازی آرایه مان نیاز داریم! اما این همه اش نیست! مزیت دیگر استفاده ار مجموعه بیتی، method های تعریف شده در این کلاس است که کار با اعداد دودویی را بسیار راحت می کند. برای مثال تبدیل اعداد دهدهی به دودویی و برعکس، ایجاد مقدار هش شده از عدد دودویی، چاپ یکباره کل آرایه روی خروجی، به دست آوردن تعداد یک های موجود در آرایه و … تنها با یک فراخوانی انجام می شود!

برای استفاده از مجموعه بیتی در برنامه ++C تان لازم است که سرفایل 

<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 می توانید مجموعه بیتی پویا داشته باشید! به اینجا سری بزنید!

Digg This  Reddit This  Stumble Now!  Buzz This  Vote on DZone  Share on Facebook  Bookmark this on Delicious  Kick It on DotNetKicks.com  Shout it  Share on LinkedIn  Bookmark this on Technorati  Post on Twitter  Google Buzz (aka. Google Reader)  



برچسب ها : ,