C conversions, bitwise operations और sequencing
उद्देश्य और भाषा का contract
Basic C expression tracing से आगे बढ़कर पहले types तय करें, unsigned wrap को signed overflow से अलग रखें और grouping को evaluation order न समझें। यहाँ ISO C11/C17 है। 32-bit int, आठ-bit byte, two's-complement signed representation या signed plain char स्वतः नहीं मानते। जिन संख्यात्मक उदाहरणों को अतिरिक्त धारणाएँ चाहिए, उनमें वे दी हैं। आवश्यक standard headers, valid initialized objects और concurrent access न होना मानें। Compiler का एक output undefined behavior को portable उत्तर नहीं बनाता।
1. Arithmetic से पहले promotions
Integer promotions char, signed/unsigned char और signed/unsigned short को int बनाते हैं, यदि int उनकी पूरी range रख सकता है; अन्यथा unsigned int। इसलिए दो unsigned char का जोड़ आवश्यक नहीं कि उसी छोटे type में हो। CHAR_BIT=8 तथा int की range कम-से-कम −32767..32767 मानें। unsigned char a=250,b=10; में a+b का type int और value 260 है। इसे unsigned char c में रखने पर modulo 256 conversion से 4 मिलेगा। Expression और destination के types अलग हो सकते हैं।
Usual arithmetic conversions उपयोग करने वाले operators (जैसे arithmetic + तथा relational <) के दो integer operands में पहले integer promotions, फिर ये conversions होते हैं। Shifts और logical operators के नियम अलग हैं। समान signedness में higher rank चुनते हैं। Mixed signed/unsigned में unsigned की rank कम नहीं है तो unsigned type चुनें। Signed की rank अधिक है तो देखें कि वह unsigned की पूरी range रख सकता है या नहीं: हाँ तो signed type, नहीं तो उसी signed type का corresponding unsigned type। केवल “unsigned हमेशा जीतता है” सही नियम नहीं; rank और range दोनों चाहिए।
उदाहरण: −1 < 1u false है। −1 int है; comparison उसे unsigned int में बदलकर UINT_MAX बनाता है, जो 1 से बड़ा है। इसके लिए 32 bits की धारणा नहीं चाहिए। लेकिन यदि 64-bit long सभी 32-bit unsigned int values रख सकता है, तो −1L < 1u true होगा: comparison long में होता है।
Integer division zero की ओर truncate होता है: −7/3=−2 और −7%3=−1। जब b nonzero और quotient representable हो, a=(a/b)b+a%b। यदि INT_MIN/−1 का quotient representable नहीं, तो undefined behavior; zero से division भी undefined। Integer को unsigned में बदलना maximum+1 के modulo में है। Out-of-range signed integer conversion C11/C17 में implementation-defined result या implementation-defined signal देता है; portable wrap नहीं। Floating से integer conversion fractional भाग हटाता है, लेकिन बचा integral value representable न हो तो undefined behavior; integer वाला modulo rule यहाँ नहीं लगाएँ।
2. Bitwise operations के लिए type/width स्पष्ट करें
Predictable bit patterns के लिए unsigned operands लें। unsigned int x=12u के low bits 1100 हैं: x & 10u=8u, x | 3u=15u, x ^ 10u=6u। लेकिन logical x && 10u का int result 1 है, क्योंकि दोनों nonzero हैं। ~x promoted type के सभी bits flip करता है, केवल लिखे हुए चार नहीं। ~0u हमेशा UINT_MAX है।
जब promoted left operand का type W value-bit unsigned हो, तब 0≤k<W के लिए x<<k, x को 2^k से गुणा करके modulo 2^W है; x>>k, 2^k से division का floor है। छोटा unsigned operand signed int में promote हो सकता है: आठ-bit unsigned char तथा 510 represent कर सकने वाले int में unsigned char c=255; c<<1 का type int और value 510 है, 254 नहीं। Negative count या promoted left operand की width जितना/उससे बड़ा count undefined behavior है। C11/C17 में signed left shift के लिए operand nonnegative तथा signed result representable चाहिए; अन्यथा undefined behavior। Negative signed value का right shift implementation-defined है। Implementation बताए बिना −4>>1 को −2 न लिखें।
Bit k का mask 1u<<k केवल unsigned int की valid range में बनाएँ। (flags & mask) != 0 selected bit जाँचता है। flags & mask == 0 का parse flags & (mask == 0) है: equality की precedence bitwise AND से अधिक है। इच्छित grouping के लिए parentheses आवश्यक हैं।
3. Grouping और sequencing अलग हैं
Precedence/associativity syntax tree तय करती हैं, operands का समय-क्रम सामान्यतः नहीं। + operands तथा function arguments के लिए left-to-right guarantee नहीं। C11/C17 में i++ + i और f(i++, i++) में i पर unsequenced conflicting accesses हैं: undefined behavior। अलग-अलग संभावित numerical outputs में से उत्तर न चुनें।
&& में left पहले आता है; zero होने पर right skip। || में left nonzero हो तो right skip। ?: में condition के बाद केवल selected branch चलती है। Comma operator left expression को right से पहले sequence करता है; function arguments अलग करने वाला comma यह operator नहीं। अलग full-expression statements भी sequencing देते हैं।
सुरक्षित trace: int i=0; int r=(i++ && ++i); से i=1,r=0। Left पुराना zero देता है, i बढ़ाता है, फिर ++i नहीं चलता। && को & बनाने पर short-circuit नहीं होगा और unsequenced modifications से undefined behavior होगा। सुरक्षित explicit विकल्प: int a=i++; int b=i; int r=a+b; में i शुरू में 2 हो तो a=2,b=3,r=5,i=3।
परीक्षा checklist और गलतियाँ
Promoted types लिखें, conversions करें, representability तथा shift bounds जाँचें, फिर sequencing की वैधता जाँचकर value निकालें। Unsigned wrap defined है; signed overflow undefined; implementation-defined के लिए documented choice चाहिए। बिना conflicting accesses के unspecified order आवश्यक नहीं कि undefined हो: independent g और h वाले f(g(),h()) में दोनों का क्रम बदल सकता है। इन श्रेणियों को न मिलाएँ।
मौलिक अभ्यास: छह single-correct MCQs
ये मौलिक शिक्षण प्रश्न हैं, previous-year questions नहीं। एक विकल्प चुनें।
P01. CHAR_BIT=8 और int में 0..65535 representable हैं। unsigned char a=250,b=10; assignment से पहले a+b क्या है?
A. int 260 B. unsigned char 4 C. unsigned int 260 D. Undefined behavior
उत्तर: A
A: दोनों int में promote होकर 260 देते हैं।
B: Modulo 256 वापस छोटे type में रखने पर है।
C: पूरी range int में है, इसलिए unsigned int नहीं।
D: धारणा के int में 260 representable है।
P02. C11/C17 में −1 < 1u की value?
A. 1 B. 0 C. सदैव implementation-defined D. सदैव undefined
उत्तर: B
A: Comparison signed int में नहीं है।
B: −1, UINT_MAX बनकर 1 से बड़ा है।
C: Fixed width बिना भी परिणाम portable है।
D: Unsigned conversion defined है।
P03. unsigned int x=12u में x ^ 10u क्या है?
A. 8 B. 14 C. 6 D. 1
उत्तर: C
A: 8 यहाँ AND है।
B: 14 यहाँ OR है।
C: 1100 XOR 1010 = 0110।
D: 1 logical truth value हो सकती है, XOR नहीं।
P04. flags & mask == 0 की grouping क्या है?
A. (flags & mask) == 0 B. flags & (mask == 0) C. (flags == mask) & 0 D. Syntax error है
उत्तर: B
A: इस intended bit test को parentheses चाहिए।
B: Equality की precedence bitwise AND से अधिक है।
C: Precedence operands इस तरह नहीं बदलती।
D: Syntax valid है; अर्थ अक्सर गलत होता है।
P05. i=0 से int r=(i++ && ++i); के बाद:
A. i=2,r=1 B. i=1,r=1 C. Undefined behavior D. i=1,r=0
उत्तर: D
A: Right operand skip होता है।
B: Left zero देता है, result zero है।
C: Short-circuit sequencing इसे defined बनाती है।
D: i++ zero देकर एक बार बढ़ाता है; ++i skip।
P06. Initialized int i=2 के लिए C11/C17 में किस fragment का behavior undefined है?
A. int r=i+3; B. int r=(i++,i); C. int r=i++ + i; D. int r=(i>0 ? i : 0);
उत्तर: C
A: यह representable सामान्य sum है।
B: Comma operator increment के बाद read कराता है।
C: i का modification और अलग value read unsequenced हैं।
D: Conditional में conflicting modification नहीं।
स्रोत और दायरा
GATE CS 2026 के मौजूदा आधार-पाठों का सीमित विस्तार। पूरे विषय की पूर्णता का दावा नहीं। उदाहरण और प्रश्न मौलिक हैं।
प्रगति सहेजने के लिए साइन इन करें। साइन इन