5.1.2 · Coding › C Programming
Intuition Ek-sentence idea
Ek C data type ek contract hai jo compiler ko batata hai ki memory mein kitne bytes reserve karne hain aur un bits ko kaise interpret karna hai (integer, character code, ya floating-point number ke roop mein).
Memory bas bytes ki ek lambi line hai — raw 0s aur 1s. Wahi bit pattern 0100 0001 ka matlab number 65, character 'A', ya kisi float ka hissa ho sakta hai. Type woh lens hai jiske through CPU un bits ko padhta hai. Uske bina, machine ko pata nahi chal sakta ki kitne bytes uthane hain ya kaunsa operation (integer add vs. float add — alag circuits!) run karna hai.
Ek data type specify karta hai (1) bytes mein size , (2) interpretation (integer / character / floating), aur (3) ek variable ke liye representable values ki range .
Common mistake Steel-man: "
int hamesha 4 bytes hota hai."
Kyun sahi lagta hai: har PC par jispe tumne kaam kiya, sizeof(int)==4.
Fix: C standard sirf itna guarantee karta hai ki int ≥ 16 bits ho aur ordering ye ho:
sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long) .
Agar portability matter karti hai toh hamesha sizeof use karo. sizeof(char) == 1 akela size hai jo standard fix karta hai.
Hum isse first principles se derive karte hain — bit patterns ko count karke.
Intuition First principle
n bits se exactly 2 n distinct patterns ban sakte hain (har bit 0 ya 1 hai, aur choices multiply hoti hain).
Unsigned (unsigned char, size_t, …): har pattern ek non-negative value hai.
range = [ 0 , 2 n − 1 ]
− 1 kyun? Kyunki zero 2 n slots mein se ek kha leta hai, isliye largest value count se ek kam hoti hai.
Signed (two's complement, jo C practically use karta hai): ek bit ki "weight" ko negative banaya jaata hai taaki hum negatives encode kar sakein. Hum 2 n patterns ko negatives aur non-negatives mein split karte hain:
range = [ − 2 n − 1 , 2 n − 1 − 1 ]
Ye asymmetric kyun hai (positives se ek zyada negative)? Pattern 1000…0 most-negative value ke liye reserved hai; zero positive side par baitha hai, ek positive slot "use kar ke". Isliye tumhe 2 n − 1 negatives milte hain lekin sirf 2 n − 1 − 1 positives.
signed char (n = 8 bits)
Total patterns: 2 8 = 256 . Kyun? 8 independent bits.
Range: [ − 2 7 , 2 7 − 1 ] = [ − 128 , 127 ] . Kyun? n = 8 ke saath signed formula apply karo.
unsigned char: [ 0 , 255 ] . Kyun? Unsigned formula 2 8 − 1 = 255 apply karo.
int (n = 32 bits)
Range: [ − 2 31 , 2 31 − 1 ] = [ − 2 , 147 , 483 , 648 , 2 , 147 , 483 , 647 ] .
Ye kyun matter karta hai: INT_MAX mein 1 add karo aur woh wrap ho jaata hai (unsigned ke liye) ya undefined behaviour hota hai (signed ke liye). Ye classic integer-overflow bug hai.
Intuition Floats "bade ints" kyun nahi hain
Integers count karte hain; floats measure karte hain . Limited bits se ek bade range (atoms se galaxies tak) ko cover karne ke liye, hum numbers ko scientific notation ki tarah store karte hain: ek sign, ek mantissa (digits), aur ek exponent (scale). Precision relative hoti hai, absolute nahi.
Worked example Precision ke decimal digits
float mein 23 explicit + 1 implicit = 24 mantissa bits hain.
24 × log 10 2 ≈ 24 × 0.301 ≈ 7.2 → ~7 significant decimal digits .
Ye step kyun? Har bit ≈ log 10 2 decimal digits ke barabar hai; bit count se multiply karo.
double: 53 × 0.301 ≈ 15.95 → ~15–16 digits .
Common mistake Steel-man: "0.1 + 0.2 == 0.3"
Kyun sahi lagta hai: decimal mein ye obviously true hai.
Fix: 0.1 aur 0.2 ka koi finite binary representation nahi hai (jaise 1/3 ka koi finite decimal nahi). Unhe round kiya jaata hai, isliye 0.1 + 0.2 == 0.30000000000000004. Floats ko kabhi == se compare mat karo; fabs(a-b) < epsilon compare karo.
size_t
size_t ek unsigned integer type hai, <stddef.h> mein defined, machine par largest possible object ka size hold karne ke liye kaafi bada . Ye sizeof aur strlen ke return type hain.
Intuition Ek special type kyun?
Ek size kabhi negative nahi ho sakta, aur use machine ke addressable memory ke saath scale karna chahiye (isliye 64-bit par ye 64-bit hai). Size ke liye int use karna (a) sign ko waste karta aur (b) huge arrays par overflow karta. Ise %zu se print karo.
Common mistake Steel-man:
for (int i = strlen(s)-1; i >= 0; i--) se loop karna theek hai.
Kyun sahi lagta hai: 0 tak neeche count karna natural lagta hai.
Fix: agar tum size_t i use karo, toh i >= 0 hamesha true hota hai (unsigned 0 se neeche nahi ja sakta) → infinite loop, aur 0u - 1 ek bade number par wrap ho jaata hai. Signed/unsigned mix karna comparisons ko silently tod deta hai.
Worked example Forecast-then-Verify
char c = 200 ; // signed char range is [-128,127]
unsigned char u = 200 ;
printf ( " %d %d\n " , c, u);
Forecast: 200 [-128,127] se bahar hai. Two's complement mein, 200 − 256 = − 56 , isliye c -56 ban jaata hai. u 200 rehta hai.
Kyun? 200 = 1100 1000. Unsigned ke roop mein = 200. Signed ke roop mein, top bit set hai → value = 200 − 256 = − 56 .
Verify (output): -56 200. ✅
Recall Quick self-test (answers cover karo)
n -bit signed integer ki range? → [ − 2 n − 1 , 2 n − 1 − 1 ]
Woh akela type jiska sizeof standard fix karta hai? → char (== 1)
float ke liye ~7 digits kyun? → 24 mantissa bits × log 10 2
sizeof ka return type? → size_t (unsigned)
0.1+0.2 == 0.3? → false (binary rounding)
n bits se kitne distinct bit patterns exist karte hain? 2 n
n-bit unsigned integer ki range? [ 0 , 2 n − 1 ]
n-bit signed (two's complement) integer ki range? [ − 2 n − 1 , 2 n − 1 − 1 ]
Signed range asymmetric kyun hai (ek zyada negative)? Pattern 1000…0 most-negative value encode karta hai, aur 0 positive side par ek slot use karke baitha hai.
Signed char (8 bits) ki range? [ − 128 , 127 ]
Unsigned char (8 bits) ki range? [ 0 , 255 ]
32-bit int ki range? [ − 2147483648 , 2147483647 ]
Kin type ka sizeof standard ke hisaab se 1 guaranteed hai? char
C mein integer sizes ki guaranteed ordering? char ≤ short ≤ int ≤ long ≤ long long
IEEE-754 float bit layout (sign/exp/mantissa)? 1 / 8 / 23, bias 127
IEEE-754 double bit layout? 1 / 11 / 52, bias 1023
Ek normalized IEEE-754 number ki value formula? ( − 1 ) s × ( 1. f ) 2 × 2 e − bias
Float mein ~7 decimal digits of precision kyun hoti hai? 24 mantissa bits × log10(2) ≈ 7.2
Double precision ke approximate decimal digits? ~15–16 (53 bits × log10(2))
size_t kya hai? Ek unsigned type jo kisi bhi object ka size hold karne ke liye kaafi bada ho; sizeof ke dwara return hota hai.
size_t ke liye printf format specifier? %zu
"size_t i; i >= 0" countdown loop mein bug kyun hai? Unsigned kabhi < 0 nahi ho sakta, isliye ye hamesha true hota hai → infinite loop aur wrap-around.
C mein 0.1+0.2 != 0.3 kyun hai? 0.1 aur 0.2 ka koi finite binary representation nahi, isliye unhe round kiya jaata hai.
Recall Feynman: ek 12-saal ke bachche ko samjhao
Choti labelled boxes imagine karo. Ek char box bahut chhota hai — usme ek letter ya ek chhota number fit hota hai. Ek int box bada hai — usme normal counting numbers fit hoti hain. Ek double box special hai: sirf count karne ki jagah, ye number ko "scientific notation" form mein yaad rakhta hai (kuch digits + dot kahan jaata hai), isliye ye bahut bade ya bahut chhote numbers hold kar sakta hai lekin sirf ~15 trustworthy digits ke saath. size_t woh box hai jo hum kehne ke liye use karte hain "ye cheez kitni badi hai?" — aur kyunki kisi cheez ka size kabhi negative nahi hota, woh box sirf 0 aur usse upar hold karta hai. Box par lagaa label computer ko batata hai ki box kitna bada hai aur andar kya hai use kaise padhna hai.
"Char Sips Iced Latte, Floating Doubles" → Char (1) S hort(2) I nt(4) L ong(8), Float (4) Double (8). Aur size_t = "size that fits the whole place" → pointer jitna wide.
Two's Complement Representation — kyun signed ranges asymmetric hain
Integer Overflow and Undefined Behaviour — range ke baad kya hota hai
IEEE-754 Floating Point — full mantissa/exponent derivation
sizeof Operator — compile time par sizes kaise query karein
Type Conversion and Promotion — jab types mix hoti hain toh kya hota hai
Pointers and Addresses — kyun size_t pointer width se match karta hai
only fixed sizeof char equals 1
Memory raw bytes 0s and 1s
Unsigned range 0 to 2^n-1
Signed range -2^n-1 to 2^n-1 -1
char le short le int le long