5.1.23 · D3 · Coding › C Programming › Bit fields in structs
Parent: Bit Fields in Structs
Is page mein hum bit-field ke poore zoo of situations cover karte hain. Solve karne se pehle hum terrain map karte hain, taaki tumhe dikh sake ki humne kuch chhoda nahi.
Har bit-field puzzle jo tumhe kabhi milega, woh neeche diye gaye cells mein se kisi ek mein fit hoga. Hum cell ka naam denge, phir baad mein kam se kam ek example solve karenge jo seedha usi cell mein aata hai.
#
Case class
Kya tricky hai
Covered by
A
Width choose karna
sabse chhota N choose karo jahan 2 N ≥ needed values
Ex 1
B
Unsigned overflow (wrap)
value zyada badi → sirf low N bits rakho
Ex 2
C
Signed field, positive value
top bit sign hai, value nahi
Ex 3
D
Signed field, value jo negative ho jaati hai
sign bit ka meaning flip ho jaata hai
Ex 3, Ex 4
E
Zero / degenerate value
0 store karna, aur all-ones maximum
Ex 5
F
Packing & sizeof
fields ek storage unit share kaise karte hain
Ex 6
G
Zero-width alignment trick
naya storage unit force karna
Ex 7
H
Real-world word problem
ek hardware status register
Ex 8
I
Exam twist (address / illegal op)
&s.field compile nahi hoga
Ex 9
Neeche sara arithmetic sirf do chhote tools se hoga, toh pehle unhe samajh lete hain.
Definition Do tools jo hum baar baar use karenge
"Fits" question: ek N -bit box mein kitne distinct values aa sakte hain? Har bit ek 2-position switch hai, aur switches multiply hote hain, isliye ek N -bit box mein ==2 N == values aate hain (dekho Data types and sizeof — kyon ek bit ek switch hai).
"Wrap" question: ek zyada badi value v N bits mein kya ban jaati hai? N width ka box sirf last N binary digits yaad rakh sakta hai. Low N bits tak kaat dena exactly 2 N se divide karne ke baad remainder lene jaisa hai. Hum likhte hain ==v mod 2 N == ("v modulo two-to-the-N"). mod symbol ka matlab bas "remainder lo" hai.
Upar ki picture har example ke liye mental model hai: numbered slots ki ek row, left se fill ho rahi hai, aur ek value jo "edge se gir jaati hai" jab woh zyada wide hoti hai.
Worked example Weekday ke liye kitni wide?
Tumhe ek weekday number 1–7 store karna hai. Sabse narrow unsigned bit field declare karo jo kaam kare.
Forecast: aage padhne se pehle bit count guess karo. (Dhyan se: kya woh 3 hai ya 4?)
Jinhe represent karna hai unki values count karo. Days 1..7 matlab 7 distinct values.
Yeh step kyun? Width question hamesha "kitne distinct values" hoti hai, kabhi bhi sirf "sabse bada number kitna hai" nahi — haalaanki yahan dono almost agree karte hain.
2 N ≥ 7 solve karo. 2 2 = 4 < 7 , 2 3 = 8 ≥ 7 . Toh N = 3 .
Yeh step kyun? 2 N woh count hai jo ek box hold karta hai (hamara pehla tool); hum chahte hain sabse chhota box jo kam se kam 7 cheezein hold kare.
Declaration likho.
unsigned int weekday : 3 ; // holds 0..7, we use 1..7
Yeh step kyun? unsigned isliye ki weekdays kabhi negative nahi hote; 3 bits isliye ki yahi step 2 ka answer hai.
Verify: ek 3-bit box 0 … 7 hold karta hai — jo 1..7 ko comfortably contain karta hai aur value 0 spare rehti hai. Ek 2-bit box maximum 3 tak jaata hai, jo Thursday tak bhi nahi pahunch sakta. ✓
Worked example 4-bit field mein 20 store karo
struct { unsigned q : 4 ; } s;
s.q = 20 ;
printf ( " %u\n " , s.q);
Forecast: kaunsa number print hoga? (Yeh error nahi hai, aur 20 bhi nahi hai.)
Box ki capacity nikalo. 4 bits mein 2 4 = 16 values aati hain, yaani 0 … 15 . Kyunki 20 > 15 , yeh fit nahi hota.
Yeh step kyun? Pehle jaanna zaroori hai ki wrap hoga bhi ya nahi.
20 ko binary mein likho. 20 = 16 + 4 = 1010 0 2 (paanch digits).
Yeh step kyun? Box sirf low 4 binary digits rakhta hai, toh hume woh digits dekhne hain.
Low 4 bits rakho. 1 010 0 2 mein se leftmost bit hataao → 010 0 2 = 4 .
Yeh step kyun? Ek 4-slot box physically 5th digit store nahi kar sakta — woh edge se gir jaata hai (s01 figure mein "overflow" arrow dekho).
Wrap tool se cross-check karo. 20 mod 16 = 4 .
Yeh step kyun? Modulo simply steps 2–3 ka fast version hai bina bits draw kiye.
Verify: program 4 print karta hai, aur 20 − 16 = 4 match karta hai. ✓
signed field kya store karta hai?
struct { signed int x : 3 ; } s;
s.x = 3 ; printf ( " %d\n " , s.x); // case C
s.x = 6 ; printf ( " %d\n " , s.x); // case D
Forecast: dono outputs guess karo. (Doosra sabko surprise karta hai.)
Signed 3-bit field ki legal range list karo. Ek bit sign hai, toh values − 2 2 … 2 2 − 1 = − 4 … 3 chalti hain.
Yeh step kyun? Signed aur unsigned same bits share karte hain lekin top bit ko alag interpret karte hain.
Case C: 3 store karo. 3 is − 4 … 3 ke andar hai, toh exactly rakha jaata hai. 3 print hota hai.
Yeh step kyun? Koi wrap nahi, koi sign issue nahi — yeh easy case hai, dikhaya taaki tum mechanism pe trust karo.
Case D: 6 store karo. Pehle 3 bits tak truncate karo: 6 = 11 0 2 , pehle se 3 bits hai, toh raw bits hain 110 .
Yeh step kyun? Overflow-truncation sign padhne se pehle hoti hai.
Un bits ko signed ke roop mein re-interpret karo. Top bit 1 hai → negative. 11 0 2 ki two's-complement value hai 6 − 2 3 = 6 − 8 = − 2 . -2 print hota hai.
Yeh step kyun? Signed box mein leading 1 ka matlab hai "2 N ghatao" — yahi "sign bit" karta hai (dekho Unsigned vs signed integers ).
Verify: 6 mod 8 = 6 raw bits ke roop mein; kyunki 6 ≥ 2 2 = 4 , signed value hai 6 − 8 = − 2 . ✓
Common mistake Signed fields ke liye "3 bits, toh 0..7"
Ek signed 3-bit field 0..7 nahi hai; yeh − 4..3 hai. Agar tum 0..7 chahte ho, unsigned likho. Yeh exam ka sabse common trap hai.
Worked example 5-bit signed field ka floor
signed int f : 5; sabse chhota kaunsa number hold kar sakta hai, aur uska bit pattern kaunsa hai?
Forecast: minimum guess karo. (Hint: yeh maximum ke saath symmetric nahi hai.)
Signed range formula apply karo. N = 5 : range − 2 4 … 2 4 − 1 = − 16 … 15 .
Yeh step kyun? Hamara signed formula directly use kar rahe hain.
− 16 ka bit pattern nikalo. Two's complement: − 16 = − 32 + 16 = 1000 0 2 .
Yeh step kyun? Hum degenerate extreme ko dekhna chahte hain, sirf naam nahi lena.
Asymmetry notice karo. Max hai + 15 , min hai − 16 ; positive se ek zyada negative hai kyunki 0 positive side pe baitha hai.
Yeh step kyun? Yeh limiting behaviour ek classic "off-by-one" exam target hai.
Verify: − 16 ≤ − 16 ≤ 15 ✓ aur 1000 0 2 = 16 − 32 = − 16 ✓.
Worked example Ek 8-bit unsigned register ke dono extremes
unsigned int reg : 8; ke liye, 0 store karne par kya milta hai, aur sabse bada storable value aur uske bits kya hain?
Forecast: do numbers — floor aur ceiling.
Zero degenerate low case hai. 0 store hota hai 0000000 0 2 ke roop mein; wrap kuch nahi. 0 wapas read hota hai.
Yeh step kyun? Hamesha confirm karo ki trivial input sahi behave karta hai — yeh ek free correctness check hai.
Maximum all ones hai. Largest unsigned value = 2 8 − 1 = 255 = 1111111 1 2 .
Yeh step kyun? "All ones" ek full box ka visual signature hai (saare slots on hain).
Agar tum 256 store karo toh? 256 = 10000000 0 2 (9 bits) → low 8 bits saare zero hain → 0 pe wrap hota hai, Cell E ke floor jaisa.
Yeh step kyun? Dikhata hai ki ceiling aur floor number circle pe neighbours hain: 255 ke baad 0 aata hai.
Verify: 2 8 − 1 = 255 ✓ aur 256 mod 256 = 0 ✓.
Worked example Kitne bytes?
struct S {
unsigned a : 5 ;
unsigned b : 5 ;
unsigned c : 25 ;
};
printf ( " %zu\n " , sizeof ( struct S)); // typical 32-bit-unit compiler
Forecast: sizeof guess karo. (Kya yeh 4 hai? 8? Kuch aur?)
a place karo. Pehle 32-bit unit ke slots 0–4 lete hai. Baaki free slots: 27.
Yeh step kyun? Compiler ek storage unit left-to-right fill karta hai, ek offset track karte hue (dekho Memory alignment and padding ).
b place karo. Slots 5–9 lete hai. Baaki free slots: 22.
Yeh step kyun? Same rolling offset; abhi bhi unit 1 ke andar comfortably hai.
c (25 bits) place karne ki koshish karo. Unit 1 mein sirf 22 slots bacha hain, lekin c ko 25 chahiye. Yeh fit nahi hota .
Yeh step kyun? Ek field unit ke end se straddle nahi kar sakti yahan, toh use jump karna hoga.
c ke liye fresh unit start karo. Ab struct do 32-bit units span karta hai = 2 × 4 = 8 bytes.
Yeh step kyun? sizeof poore storage units count karta hai jo use hue hain, bits nahi.
Verify (bit accounting): unit 1 mein 5 + 5 = 10 ≤ 32 bits hain ✓; 10 + 25 = 35 > 32 jump force karta hai ✓; total units = 2 , toh sizeof = 8 . ✓
Worked example Naya storage unit force karo
struct R {
unsigned low : 4 ;
unsigned : 0 ; // the trick
unsigned high : 4 ;
};
low aur high kahan rahenge, aur (32-bit-unit compiler pe) sizeof(struct R) kya hoga?
Forecast: kya low aur high ek unit share karte hain ya nahi?
low place karo. Unit 1 ke slots 0–3.
Yeh step kyun? Normal packing.
unsigned : 0; marker hit karo. Ek unnamed zero-width field kuch store nahi karta lekin kehta hai "next unit boundary pe flush karo."
Yeh step kyun? Yahi is trick ka poora point hai — deliberate alignment, data nahi.
high place karo. Flush ki wajah se, high unit 2 ke slot 0 pe start karta hai, unit 1 ke slot 4 pe nahi.
Yeh step kyun? Useful jab hardware layout mirror kar rahe ho jahan do fields alag registers mein honi chahiye.
Units count karo. Do units touch hue → sizeof = 8 bytes.
Yeh step kyun? Example 6 jaisi "whole units" rule.
Verify: trick ke bina dono 4-bit fields ek unit mein fit ho jaate (4 + 4 = 8 ≤ 32 , sizeof=4); zero-width field ne high ko naye unit pe push kar diya, toh sizeof 8 ho jaata hai. ✓
Worked example Motor-controller status byte decode karo
Ek chip ek 8-bit status register expose karta hai. C mein hum ise mirror karte hain (dekho Embedded systems / hardware registers ):
struct Status {
unsigned ready : 1 ; // bit 0
unsigned dir : 1 ; // bit 1 (0=fwd, 1=rev)
unsigned speed : 3 ; // bits 2..4 (0..7)
unsigned error : 3 ; // bits 5..7 (fault code)
};
Hardware raw byte 0b110_101_1_0 report karta hai error speed dir ready ke roop mein grouped = 110 101 1 0. Har field decode karo.
Forecast: decode karne se pehle ready, dir, speed, error guess karo.
Byte ko declared widths se split karo. Grouping padhte hue: ready=0, dir=1, speed=101₂, error=110₂.
Yeh step kyun? Har field ek fixed slice own karta hai; decoding sirf sahi widths pe slicing hai.
ready = 0 → motor ready nahi hai.
Yeh step kyun? Ek 1-bit field plain flag hai: sirf 0/1 (2 1 = 2 values).
dir = 1 → direction reverse hai.
Yeh step kyun? Same 1-bit flag, meaning datasheet se fixed hai.
speed = 101₂ = 5. Unsigned 3-bit, range 0..7.
Yeh step kyun? 3-bit slice ko number mein convert karo (4 + 0 + 1 = 5 ).
error = 110₂ = 6. Fault code 6.
Yeh step kyun? Top slice ke liye same conversion (4 + 2 + 0 = 6 ).
Verify: widths ka sum 1 + 1 + 3 + 3 = 8 bits = exactly ek byte ✓; decoded values 0 , 1 , 5 , 6 mein se har ek apne field ki range mein hai (< 2 , < 2 , < 8 , < 8 ) ✓.
Worked example Compile error dhundho
struct { unsigned flag : 1 ; } s;
unsigned * p = & s.flag; // (A)
unsigned t = s.flag;
unsigned * q = & t; // (B)
Kaunsi line compile fail karti hai, aur intent ko kaise bachaya jaaye?
Forecast: guess karo ki (A)/(B) mein se kaunsa break karta hai.
& ko kya chahiye recall karo. & operator ko ek byte address chahiye; C addresses poore bytes pe point karte hain, kabhi single bit pe nahi.
Yeh step kyun? Yahi woh rule hai jis par yeh twist build hui hai (contrast karo Bitwise operators se, jo bits manipulate karte hain bina unka address jaane).
Line (A) fail hoti hai. flag shayad ek byte ke andar bit 0 pe baith sakta hai — uska koi byte address nahi hai, toh &s.flag ek compile error hai.
Yeh step kyun? Step 1 directly apply hota hai.
Line (B) theek hai. t ek ordinary unsigned hai jo apne bytes mein rehta hai, toh &t legal hai.
Yeh step kyun? Ek normal variable mein copy karna value ko ek real address deta hai.
Rescue pattern. Address ki zaroorat se pehle bit field ko hamesha ek plain variable mein copy karo.
Yeh step kyun? Yeh standard idiom hai aur expected exam answer hai.
Verify (logic): exactly line (A) reject hoti hai; copy ke baad, t == s.flag aur &t valid hai. Check karne ke liye koi arithmetic nahi — yeh claim ek rule hai, jo C standard ke "bit fields are not addressable" se confirm hota hai. ✓
Recall Kya har cell cover hua?
Matrix ke har row ko uske example se match karo :::
A→Ex1, B→Ex2, C&D→Ex3+Ex4, E→Ex5, F→Ex6, G→Ex7, H→Ex8, I→Ex9. Har cell hit hua. :::
Fast recall: 13 ek 3-bit unsigned field mein store hoga toh kya? ::: 13 mod 8 = 5 .
Fast recall: signed 5-bit range? ::: − 16 … 15 .
"Slice, then Wrap; Sign steals a bit; No &." — widths se slice karke decode karo, zyada badi values ko mod 2 N se wrap karo, yaad rakho ki signed fields top bit kho deti hain, aur kabhi bit field ka address mat lo.
Bit Fields in Structs — parent concept.
Structs in C — woh container jisme yeh examples rehte hain.
Bitwise operators — bit fields ke bina manual slicing.
Data types and sizeof — kyon ek bit ek 2-state switch hai aur units int-sized hote hain.
Memory alignment and padding — Example 6 & 7 ke packing rules.
Embedded systems / hardware registers — Example 8 ka real-world use.
Unsigned vs signed integers — Examples 3–4 mein sign-bit logic.