विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

C++ bit-field

लेखक के बारे में:

व्यक्तिगत WeChat सार्वजनिक अकाउंट:

wechat

Bit field क्या है?

"bit field" यानी बिट-फ़ील्ड एक डेटा स्ट्रक्चर है, जो डेटा को बिट्स के रूप में संक्षिप्त ढंग से स्टोर कर सकता है और प्रोग्रामर को इस स्ट्रक्चर के बिट्स पर ऑपरेशन करने देता है। इस डेटा स्ट्रक्चर का एक फ़ायदा यह है कि यह डेटा यूनिट के लिए storage space बचा सकता है, जब प्रोग्राम को हज़ारों-लाखों डेटा यूनिट चाहिएँ, तो यह तरीका और भी महत्वपूर्ण हो जाता है। दूसरा फ़ायदा है कि bit field से किसी integer वैल्यू के हिस्से को आसानी से एक्सेस किया जा सकता है, जिससे प्रोग्राम का सोर्स कोड सरल होता है। और इस डेटा स्ट्रक्चर की कमी यह है कि bit field का implementationख़ास मशीन और सिस्टम पर निर्भर है, अलग platform पर अलग परिणाम मिल सकते हैं, जिसके कारण bit field अपनी प्रकृति में non-portable है।

  • bit field की मेमोरी में layout मशीन पर निर्भर है
  • bit field का टाइप integer या enum टाइप ही होना चाहिए, signed टाइप में bit field का व्यवहारख़ास implementation पर निर्भर है
  • address-of ऑपरेटर (&) bit field पर लागू नहीं हो सकता, कोई भी पॉइंटर क्लास के bit field की ओर नहीं पॉइंट कर सकता

bit field का उपयोग

bit field आमतौर पर स्ट्रक्चर से declare किया जाता है, यह स्ट्रक्चर declaration हर bit field मेंबर को नाम देती है और उसकी width तय करती है:

struct bit_field_name
{
    type member_name : width;
};
Elements Description
bit_field_name bit field स्ट्रक्चर का नाम
type bit field मेंबर का टाइप, int, signed int या unsigned int टाइप ही होना चाहिए
member_name bit field मेंबर का नाम
width मेंबर द्वारा घेरे जाने वाले बिट्स की संख्या

उदाहरण के लिए नीचे जैसा एक bit field declare करें:

struct _PRCODE
{
    unsigned int code1: 2;
    unsigned int cdde2: 2;
    unsigned int code3: 8;
};
struct _PRCODE prcode;

यह परिभाषा prcode को 2 जैसे 2 Bits के bit field और 1 जैसे 8 Bits के bit field से बनाती है, हम स्ट्रक्चर के मेंबर ऑपरेटर से उसे वैल्यू दे सकते हैं

prcode.code1 = 0;
prcode.code2 = 3;
procde.code3 = 102;

वैल्यू देते समय ध्यान रखें कि वैल्यू bit field मेंबर की capacity से बड़ी न हो, जैसे prcode.code3, 8 Bits का bit field मेंबर है, इसकी capacity 2^8 = 256 है, यानी वैल्यू की सीमा [0,255] होनी चाहिए।

bit field का साइज़ और alignment

bit field का साइज़

उदाहरण के लिए निम्नलिखित bit field:

struct box 
{
    unsigned int a: 1;
    unsigned int  : 3;
    unsigned int b: 4;
};

इस bit field स्ट्रक्चर के बीच में एक unnamed bit field है, जो 3 Bits घेरता है, केवल padding का काम करता है, कोई वास्तविक अर्थ नहीं। padding से यह स्ट्रक्चर कुल 8 Bits उपयोग करता है। लेकिन C भाषा bit field की बुनियादी इकाई unsigned int मानती है, भले ही किसी स्ट्रक्चर का एकमात्र मेंबर 1 Bit का bit field हो, उस स्ट्रक्चर का साइज़ unsigned int जितना ही होगा। कुछ सिस्टम में unsigned int 16 Bits होता है, x86 सिस्टम में 32 Bits। लेख में आगे unsigned int को 32 Bits ही माना गया है।

bit field का alignment

एक bit field मेंबर दो unsigned int की boundary पार नहीं कर सकता, अगर मेंबर declaration के कुल बिट्स unsigned int के साइज़ से बढ़ जाएँ, तो कंपाइलर bit field मेंबर को अपने-आप shift करके unsigned int की boundary पर align कर देता है। उदाहरण के लिए:

struct stuff 
{
    unsigned int field1: 30;
    unsigned int field2: 4;
    unsigned int field3: 3;
};

field1 + field2 = 34 Bits, 32 Bits से ज़्यादा, कंपाइलर field2 को अगले unsigned int यूनिट में shift करके रखेगा, stuff.field1 और stuff.field2 के बीच 2 Bits का gap रह जाएगा, stuff.field3, stuff.field2 के तुरंत बाद आएगा, अब इस स्ट्रक्चर का साइज़ 2 * 32 = 64 Bits है।

इस खाली स्थान को पहले बताए unnamed bit field मेंबर से भरा जा सकता है, हम width 0 वाले unnamed bit field मेंबर से अगले bit field मेंबर को अगले integer पर align भी कर सकते हैं। उदाहरण के लिए:

struct stuff 
{
    unsigned int field1: 30;
    unsigned int       : 2;
    unsigned int field2: 4;
    unsigned int       : 0;
    unsigned int field3: 3; 
};

यहाँ stuff.field1 और stuff.field2 के बीच 2 Bits का gap है, stuff.field3 अगले unsigned int में स्टोर होगा, अब इस स्ट्रक्चर का साइज़ 3 * 32 = 96 Bits है।

सीखने का कोड देखें: bit.cpp

bit field का initialization और बिट्स का re-mapping

initialization

bit field का initialization सामान्य स्ट्रक्चर की तरह ही होता है, यहाँ दो तरीके हैं, जैसे:

struct stuff s1= {20,8,6};

या सीधे bit field मेंबर को वैल्यू दें

struct stuff s1;
s1.field1 = 20;
s1.field2 = 8;
s1.field3 = 4;

bit field का re-mapping (Re-mapping)

32 Bits का bit field declare करें

struct box {
    unsigned int ready:     2;
    unsigned int error:     2;
    unsigned int command:   4;
    unsigned int sector_no: 24;
}b1;

re-mapping से bit field को zero करना

int* p = (int *) &b1;  // 将 "位域结构体的地址" 映射至 "整形(int*) 的地址" 
*p = 0;                // 清除 s1,将各成员归零

union से 32 Bits bit field को unsigned int टाइप में re-mapping करना

पहले union का संक्षिप्त परिचय

"union" एक विशेष क्लास है, और भी एक constructed डेटा स्ट्रक्चर। एक "union" के अंदर कई अलग-अलग डेटा टाइप परिभाषित किए जा सकते हैं, एक "union" टाइप के रूप में declare किए वेरिएबल में, उस "union" में परिभाषित कोई भी डेटा भरा जा सकता है, ये डेटा एक ही मेमोरी साझा करते हैं, ताकि जगह बचाई जा सके

"union" और "struct" में कुछ समानता है। लेकिन दोनों में मूलभूत अंतर है। struct में हर मेंबर की अपनी मेमोरी होती है, एक struct वेरिएबल की कुल लंबाई सभी मेंबरों की लंबाई का योग होती है (खाली struct को छोड़कर, साथ ही boundary adjustment न मानें तो)। जबकि "union" में सभी मेंबर एक ही मेमोरी साझा करते हैं, एक union वेरिएबल की लंबाई सबसे लंबे मेंबर की लंबाई के बराबर होती है। यह बताना चाहिए कि यहाँ साझा करने का मतलब कई मेंबर को एक साथ एक union वेरिएबल में भरना नहीं है, बल्कि इसका मतलब है कि उस union वेरिएबल को कोई भी मेंबर वैल्यू दी जा सकती है, लेकिन हर बार केवल एक ही वैल्यू, नई वैल्यू देने पर पुरानी मिट जाती है।

हम निम्नलिखित union declare कर सकते हैं:

union u_box {
  struct box st_box;     
  unsigned int ui_box;
};

x86 सिस्टम में unsigned int और box दोनों 32 Bits हैं, इस union से st_box और ui_box एक ही मेमोरी साझा करते हैं। bit field का कौन-सा बिट unsigned int के किस बिट से मेल खाता है, यह कंपाइलर और hardware पर निर्भर है। union से bit field को zero करने का कोड नीचे है:

union u_box u;
u.ui_box = 0;

सीखने के लिए रेफ़रेंस:http://www.yuan-ji.me/C-C-%E4%BD%8D%E5%9F%9F-Bit-fields-%E5%AD%A6%E4%B9%A0%E5%BF%83%E5%BE%97/

संबंधित विषय

टिप्पणियाँ