C Language
बिट-क्षेत्रों
खोज…
परिचय
C के अधिकांश चर में एक आकार है जो बाइट्स का एक अभिन्न अंग है। बिट-फ़ील्ड एक संरचना का एक हिस्सा है जो आवश्यक रूप से बाइट्स की एक अभिन्न संख्या पर कब्जा नहीं करता है; वे किसी भी संख्या में बिट्स कर सकते हैं। कई बिट-फील्ड्स को एकल स्टोरेज यूनिट में पैक किया जा सकता है। वे मानक सी का एक हिस्सा हैं, लेकिन कई पहलू हैं जो कार्यान्वयन को परिभाषित करते हैं। वे C के कम से कम पोर्टेबल भागों में से एक हैं।
वाक्य - विन्यास
- प्रकार-निर्दिष्ट पहचानकर्ता: आकार;
पैरामीटर
पैरामीटर | विवरण |
---|---|
प्रकार विनिर्देशक | signed , unsigned , int या _Bool |
पहचानकर्ता | संरचना में इस क्षेत्र का नाम |
आकार | बिट्स की संख्या इस क्षेत्र के लिए उपयोग करने के लिए |
टिप्पणियों
बिट-फ़ील्ड के लिए केवल पोर्टेबल प्रकार signed
, unsigned
या _Bool
। सादा int
प्रकार इस्तेमाल किया जा सकता है, लेकिन मानक कहते हैं (§6.7.2¶5) ... थोड़ा-क्षेत्रों के लिए, यह कार्यान्वयन से परिभाषित विनिर्देशक है कि क्या है int
निर्दिष्ट के रूप में एक ही प्रकार signed int
या के रूप में एक ही प्रकार unsigned int
।
अन्य पूर्णांक प्रकारों को एक विशिष्ट कार्यान्वयन द्वारा अनुमति दी जा सकती है, लेकिन उनका उपयोग करना पोर्टेबल नहीं है।
बिट-क्षेत्रों
एक साधारण बिट-फ़ील्ड का उपयोग उन चीजों का वर्णन करने के लिए किया जा सकता है जिनमें विशिष्ट संख्या में बिट्स शामिल हो सकते हैं।
struct encoderPosition {
unsigned int encoderCounts : 23;
unsigned int encoderTurns : 4;
unsigned int _reserved : 5;
};
इस उदाहरण में हम 23 बारीकियों के साथ एकल परिशुद्धता और 4 बिट्स को बहु-मोड़ का वर्णन करने के लिए समझते हैं। बिट-फ़ील्ड का उपयोग अक्सर हार्डवेयर के साथ इंटरफेस करते समय किया जाता है जो विशिष्ट संख्या में बिट्स से जुड़े डेटा को आउटपुट करता है। एक और उदाहरण एक FPGA के साथ संचार हो सकता है, जहाँ FPGA 32 बिट्स में आपकी मेमोरी में डेटा लिखता है जो हार्डवेयर की अनुमति देता है:
struct FPGAInfo {
union {
struct bits {
unsigned int bulb1On : 1;
unsigned int bulb2On : 1;
unsigned int bulb1Off : 1;
unsigned int bulb2Off : 1;
unsigned int jetOn : 1;
};
unsigned int data;
};
};
इस उदाहरण के लिए हमने सामान्य रूप से उपयोग किए गए निर्माण को अपने व्यक्तिगत बिट्स में डेटा तक पहुंचने में सक्षम होने के लिए, या डेटा पैकेट को संपूर्ण रूप में लिखने के लिए (एफपीजीए क्या कर सकता है) का उपयोग करके दिखाया है। हम फिर बिट्स को इस तरह एक्सेस कर सकते हैं:
FPGAInfo fInfo;
fInfo.data = 0xFF34F;
if (fInfo.bits.bulb1On) {
printf("Bulb 1 is on\n");
}
यह मान्य है, लेकिन C99 मानक 6.7.2.1, आइटम 10 के अनुसार:
एक इकाई के भीतर बिट-फ़ील्ड के आवंटन का आदेश (उच्च-ऑर्डर से कम-ऑर्डर या उच्च-ऑर्डर से कम-ऑर्डर) कार्यान्वयन-परिभाषित है।
इस तरह से बिट-फ़ील्ड्स को परिभाषित करते समय आपको एंडियननेस के बारे में पता होना चाहिए। जैसे कि मशीन की समाप्ति के लिए जांच करने के लिए प्रीप्रोसेसर निर्देश का उपयोग करना आवश्यक हो सकता है। इसका एक उदाहरण इस प्रकार है:
typedef union {
struct bits {
#if defined(WIN32) || defined(LITTLE_ENDIAN)
uint8_t commFailure :1;
uint8_t hardwareFailure :1;
uint8_t _reserved :6;
#else
uint8_t _reserved :6;
uint8_t hardwareFailure :1;
uint8_t commFailure :1;
#endif
};
uint8_t data;
} hardwareStatus;
छोटे पूर्णांक के रूप में बिट-फ़ील्ड का उपयोग करना
#include <stdio.h>
int main(void)
{
/* define a small bit-field that can hold values from 0 .. 7 */
struct
{
unsigned int uint3: 3;
} small;
/* extract the right 3 bits from a value */
unsigned int value = 255 - 2; /* Binary 11111101 */
small.uint3 = value; /* Binary 101 */
printf("%d", small.uint3);
/* This is in effect an infinite loop */
for (small.uint3 = 0; small.uint3 < 8; small.uint3++)
{
printf("%d\n", small.uint3);
}
return 0;
}
बिट-फील्ड संरेखण
बिट-फ़ील्ड संरचना फ़ील्ड को घोषित करने की क्षमता देते हैं जो चरित्र चौड़ाई से छोटे होते हैं। बिट-फ़ील्ड्स को बाइट-स्तर या शब्द-स्तरीय मास्क के साथ लागू किया जाता है। निम्न उदाहरण में 8 बाइट्स की संरचना होती है।
struct C
{
short s; /* 2 bytes */
char c; /* 1 byte */
int bit1 : 1; /* 1 bit */
int nib : 4; /* 4 bits padded up to boundary of 8 bits. Thus 3 bits are padded */
int sept : 7; /* 7 Bits septet, padded up to boundary of 32 bits. */
};
टिप्पणियां एक संभावित लेआउट का वर्णन करती हैं, लेकिन क्योंकि मानक कहता है कि पता योग्य भंडारण इकाई का संरेखण अनिर्दिष्ट है , अन्य लेआउट भी संभव हैं।
अनाम बिट-फ़ील्ड किसी भी आकार का हो सकता है, लेकिन उन्हें प्रारंभ या संदर्भित नहीं किया जा सकता है।
शून्य-चौड़ाई वाले बिट-फ़ील्ड को कोई नाम नहीं दिया जा सकता है और अगले फ़ील्ड को बिट-फ़ील्ड के डेटाटाइप द्वारा परिभाषित सीमा में संरेखित करता है। यह बिट-फ़ील्ड के बीच बिट्स को पेडिंग करके हासिल किया जाता है।
संरचना 'ए' का आकार 1 बाइट है।
struct A
{
unsigned char c1 : 3;
unsigned char c2 : 4;
unsigned char c3 : 1;
};
संरचना बी में, पहला अनाम बिट-फ़ील्ड 2 बिट्स को छोड़ देता है; शून्य चौड़ाई बिट-फ़ील्ड के बाद c2
कारण c3
3 चार सीमा से शुरू होता है (इसलिए 3 बिट्स को c2
और c3
बीच छोड़ दिया जाता है। c4
बाद 3 पैडिंग बिट्स हैं। इस प्रकार संरचना का आकार 2 बाइट्स है।
struct B
{
unsigned char c1 : 1;
unsigned char : 2; /* Skips 2 bits in the layout */
unsigned char c2 : 2;
unsigned char : 0; /* Causes padding up to next container boundary */
unsigned char c3 : 4;
unsigned char c4 : 1;
};
बिट-फ़ील्ड कब उपयोगी हैं?
एक बिट-फ़ील्ड का उपयोग संरचना के समान एक वस्तु में कई चर को एक साथ करने के लिए किया जाता है। यह कम स्मृति उपयोग के लिए अनुमति देता है और एक एम्बेडेड वातावरण में विशेष रूप से उपयोगी है।
e.g. consider the following variables having the ranges as given below.
a --> range 0 - 3
b --> range 0 - 1
c --> range 0 - 7
d --> range 0 - 1
e --> range 0 - 1
यदि हम इन चरों को अलग-अलग घोषित करते हैं, तो प्रत्येक को कम से कम 8-बिट पूर्णांक होना चाहिए और आवश्यक स्थान 5 बाइट होगा। इसके अलावा चर 8 बिट अहस्ताक्षरित पूर्णांक (0-255) की पूरी श्रृंखला का उपयोग नहीं करेंगे। यहां हम बिट-फील्ड का उपयोग कर सकते हैं।
typedef struct {
unsigned int a:2;
unsigned int b:1;
unsigned int c:3;
unsigned int d:1;
unsigned int e:1;
} bit_a;
संरचना में बिट-फ़ील्ड किसी अन्य संरचना के समान ही एक्सेस किए जाते हैं। प्रोग्रामर को ध्यान रखना होगा कि चर रेंज में लिखे गए हैं। यदि सीमा से बाहर व्यवहार अपरिभाषित है।
int main(void)
{
bit_a bita_var;
bita_var.a = 2; // to write into element a
printf ("%d",bita_var.a); // to read from element a.
return 0;
}
अक्सर प्रोग्रामर बिट-फील्ड के सेट को शून्य करना चाहता है। यह तत्व द्वारा तत्व किया जा सकता है, लेकिन दूसरी विधि है। बस एक अहस्ताक्षरित प्रकार के साथ संरचना का एक संघ बनाएं जो संरचना के आकार से अधिक या उसके बराबर है। फिर इस अहस्ताक्षरित पूर्णांक को शून्य करके बिट-फ़ील्ड्स के पूरे सेट को शून्य किया जा सकता है।
typedef union {
struct {
unsigned int a:2;
unsigned int b:1;
unsigned int c:3;
unsigned int d:1;
unsigned int e:1;
};
uint8_t data;
} union_bit;
उपयोग इस प्रकार है
int main(void)
{
union_bit un_bit;
un_bit.data = 0x00; // clear the whole bit-field
un_bit.a = 2; // write into element a
printf ("%d",un_bit.a); // read from element a.
return 0;
}
अंत में, बिट-फ़ील्ड आमतौर पर मेमोरी की कमी वाली स्थितियों में उपयोग किया जाता है जहां आपके पास बहुत सारे चर होते हैं जो सीमित सीमाओं पर ले जा सकते हैं।
बिट-खेतों के लिए डॉन
- बिट-फ़ील्ड्स की ओर इशारा करता है, बिट-फ़ील्ड्स की ओर इशारा करता है और बिट-फ़ील्ड्स पर लौटने वाले फ़ंक्शंस की अनुमति नहीं है।
- पता ऑपरेटर (&) को बिट-फील्ड सदस्यों पर लागू नहीं किया जा सकता है।
- फ़ील्ड के आकार को समाहित करने के लिए बिट-फ़ील्ड का डेटा प्रकार पर्याप्त चौड़ा होना चाहिए।
-
sizeof()
ऑपरेटर को बिट-फ़ील्ड पर लागू नहीं किया जा सकता है। - आइसोलेशन में बिट-फील्ड के लिए एक
typedef
बनाने का कोई तरीका नहीं है (हालाँकि आप निश्चित रूप से बिट-फ़ील्ड्स वाली संरचना के लिए एकtypedef
-सी बना सकते हैं)।
typedef struct mybitfield
{
unsigned char c1 : 20; /* incorrect, see point 3 */
unsigned char c2 : 4; /* correct */
unsigned char c3 : 1;
unsigned int x[10]: 5; /* incorrect, see point 1 */
} A;
int SomeFunction(void)
{
// Somewhere in the code
A a = { … };
printf("Address of a.c2 is %p\n", &a.c2); /* incorrect, see point 2 */
printf("Size of a.c2 is %zu\n", sizeof(a.c2)); /* incorrect, see point 4 */
}