CS U111 · Blocks B–C · Notes: the compressed map
Operators, I/O and selection, in one page
The rules behind every "what does this print?" question on operators, scanf, if, ?: and switch, plus the rewrite templates and the traps. This is the revision layer: first time with this material? Start with the lesson, which has a stepper for short-circuit evaluation.
This is Blocks B–C of the syllabus (lectures 4–9, Hanly & Koffman ch. 2 and ch. 4). It's the material from Labs 1–3 that felt easy at the time. The three past mid-sem papers (the predecessor course, CS F111; all in past papers) come back to it as trick questions again and again. By my tagging of each question:
| Paper | Questions on this page's topics | ≈ marks of 90 |
|---|---|---|
| 2024-25 Sem 1 | Part 1: Q1, Q2, Q3, Q5, Q7, Q12, Q14, Q15 · Part 2: the whole rewrite section (Q1–Q5) and Q6 | 43 |
| 2025-26 Sem 1 | Q1 (b, e, g), Q2 (b, d, h, i, j), Q4 (a, c, d, e, f) | 31 |
| 2025-26 Sem 2 | Part A: Q3, Q5, Q6, Q9, Q10 · Part B: Q2 (a, b); Q5 (16) is built around a switch | 21 + Q5 |
And a grounding fact: school never teaches any of this. The comma operator, short-circuit side effects, switch fall-through and scanf field widths are new to the whole batch, JEE or not. It's a closed set of about fifteen rules, and they're all below. One caveat: these papers are from the old course code. The CS U111 paper's date and format come from the Institute calendar (last year's mid-sem was 9 Oct).
The rules, one card each
1 · Integer division chops; equal ranks go left to right
"what does 2*3/4 - 3/4*2 print?"
7 / 2 // 3 (towards zero; -7/2 is -3)
2*3/4 - 3/4*2 // 6/4 - 0*2 = 1 - 0 = 1
Do * / % strictly left to right. 3/4 is already 0 before the *2.
2 · One double operand makes the operation real; a cast converts one value
averages · "the result should be a double" · (int)(…) questions
(double) sum / n // real division: 7/2 → 3.5
(double) (sum / n) // too late: 3.0
int x = 2.5; // stores 2 (clang: "changes value from 2.5 to 2")
3 · % keeps the sign of the left operand
"negative even values" · odd/even tests
-7 % 2 // -1 so x % 2 == 1 is FALSE for negative odd x
x % 2 != 0 // the safe "odd" test; x % 2 == 0 is fine for evens
4 · Comparisons give 1 or 0; nonzero means true; ! is rank 1
!x < 5 · a < b < c · "which has higher precedence than %?"
!x < 5 // (!x) < 5: always 1, since !x is 0 or 1
3 < 2 < 1 // (3<2) < 1 = 0 < 1 = 1 (Apple clang 21 refuses to compile it)
Ladder, strongest first: unary ! ++ -- (type) sizeof › * / % › + - › << >> › < <= > >= › == != › & › && › || › ?: › = += › ,
5 · && and || short-circuit: a skipped side is never run
any ++/--/assignment on the right of && or ||
a || --b // a nonzero → --b skipped, b unchanged
a && ++j // a zero → ++j skipped
!i && ++j || ++k // means (!i && ++j) || ++k
6 · Single & is bitwise: both sides always run, and "true & true" can be 0
if ((y>=0) & (x=x+1)) · bit counting
1 & 4 // 0: 001 and 100 share no bits (but 1 && 4 is 1)
6 & 3 // 2: 110 and 011 share the 2s bit
if (n & i) count++; i = i << 1; // counts 1-bits; 2273 → 5
The 2025 answer key read & as && twice: Q2b is 16 (key 14) and Q2h is 012348 (key 348). See Worked example 3.
7 · Postfix gives the old value, prefix the new; never change one variable twice
while (i++) · a-- && … · c = (a>=7) ? a++ : ++a
do { … } while (i++); // tests the OLD i: 0 stops the loop, then i is 1
i = i++ + ++i; // undefined behaviour (clang: "multiple unsequenced modifications to 'i'")
8 · Comma operator: evaluate all, keep the last
b = (a+1, c+1, 100, a+c)
int b = (a+1, c+1, 100, a+c); // b = a + c
It's the weakest operator of all, so it needs the brackets. Without them the commas mean something else.
9 · = inside a condition assigns, and the value is what was stored
if (x = 0) · (x = x + 1) inside a test
if (x = 0) … // x becomes 0; condition is 0 → always false
10 · Characters are numbers: '0'…'9' = 48…57, 'a'…'z' = 97…122, Enter = 10
"sum of the digits in a character stream" · "highest letter"
sum += c - '0'; // '7' - '0' = 7
if (c >= '0' && c <= '9') … // same as c >= 48 && c <= 57, but readable
while (c != '\n') … // '\n' is 10
11 · An else belongs to the nearest unmatched if
"for which inputs does it print s2?" · unbraced nested ifs
if (a > b) if (b > c) s1; else s2; // else pairs with (b > c)
Read the path to the target: s2 needs a > b and "not b > c", i.e. b <= c, equality included. The lesson has the decision-tree figure.
12 · c ? X : Y evaluates only the chosen branch; chains read like else-if
"rewrite using the conditional operator" · printf inside ?:
g = (s>=90)?'A' : (s>=80)?'B' : (s>=70)?'C' : (s>=60)?'D' : 'F';
(a==1) ? printf("One") : (a==2) ? printf("Two") : printf("Other");
13 · switch: jump to the matching label (else default, wherever it is), then fall through to break
missing breaks · default written first · "why does it print PositiveZero?"
switch (i) { case 2: i*=i; case 4: i*=i; default: i*=i; break; case 16: … }
// i = 2 → 4 → 16 → 256, stop at break. i = 1 → default only → 1
14 · scanf matches its format like a pattern and stops at the first mismatch
field widths · literal characters · %c · type letters
%2d, %5f // read AT MOST 2 / 5 characters (the '.' counts)
"%d-%d" // the '-' must be typed exactly; "10 20" gives n=10, m untouched
" %c" // %c takes the very next char, even a space; the leading space skips whitespace
%d int · %f float · %lf double · %Lf long double · %c char · %u unsigned
15 · printf returns the number of characters printed
"make if/else print HelloWorld" · printf inside conditions
if (!printf("Hello")) … // prints Hello, value 5, !5 = 0 → the else runs
printf("%5.2f", 3.14159); // " 3.14" (width 5, 2 decimals) %.1f of 2.75 → 2.8
The rewrite templates
Whole sections of two papers were "rewrite this using…". Each has a fixed template:
| From → to | Template | Where marks go |
|---|---|---|
switch → nested if-else, no else if | if (v==1) {…} else { if (v==2) {…} else { if (v==3) {…} else {default} } } | Each else opens braces; the default is the innermost else |
if-ladder ↔ ?: chain | x = c1 ? v1 : c2 ? v2 : … : vElse; | Same order of tests; the last value has no condition |
| ternary → if-else ladder | d = m ? (s>100 ? .2 : .1) : 0; becomes if (m && s>100) d=.2; else if (m) d=.1; else d=0; | Every path of the nested ?: becomes one rung |
for → do-while | init; do { body; update; } while (cond); | Nested: the inner init goes inside the outer body. State the zero-trip assumption |
Three worked examples at exam level
Worked example 1 · 2024 P1 Q1 (2 marks, −25% if wrong)
Short-circuit with side effects
int a = 1, b = 1;
int c = a || --b;
int d = a-- && --b;
printf("a = %d, b = %d, c = %d, d = %d", a, b, c, d);
- Write the variables in a row before reading any code:
a=1 b=1 c=? d=?. - Line 2. Left of
||isa= 1, true.||is decided, so--bis skipped:bstays 1, andc = 1. - Line 3, left side.
a--hands over the old value 1 (true), thenabecomes 0. - Line 3, right side.
&&with a true left side must evaluate the right:--bmakesb0, value 0. Sod = 1 && 0 = 0. - Read off:
a = 0, b = 0, c = 1, d = 0, which is option (b). (Option (a), b = 1, is the answer for students who forget that--bdoes run in line 3.)
Worked example 2 · 2024 P1 Q2 and Q15 (5 marks)
Parsing input with a scanf pattern
scanf("%2d %5f %2d", &n, &x, &m); with input 1234.5678 99.88 777, then printf("n= %d,x=%5.2f,m = %d", n, x, m);
- Put a cursor at the start of the input and move it piece by piece through the format.
%2d: at most 2 characters →12. n = 12. Cursor now before34.5678….- The space in the format skips whitespace; there's none here.
%5f: at most 5 characters →34.56. x = 34.56. Cursor before78 99.88…. %2d→78. m = 78. The rest of the line is never read.- Format the output:
%5.2fof 34.56 is exactly34.56(5 characters). Printed:n= 12,x=34.56,m = 78, which is option (b). - Q15, same method:
scanf("%d-%d")with input10 20.%dreads 10. The format then needs a literal-but the input has a space, soscanfstops.mkeeps its initial 0 and the output is10-0, option (c).
Both verified by compiling and piping in the exact input line. For Q15 scanf also returns 1 (one item read), which is how a real program would detect the mismatch.
Worked example 3 · 2025 Q2h (2 marks), where the official key is wrong
A printf on the right of a single &
int i, j, count;
i = 0; count = 0;
for (j = -2; j <= 2; j++) {
if ((j >= 1) & (printf("%d", i)))
count += j;
i++;
}
count += i;
printf("%d", count);
- Spot the operator. It's
&, not&&, so theprintfruns on every pass, whateverjis. Also note there are no braces: onlycount += jis inside theif, andi++runs every pass. - Trace it, one row per pass.
printf("%d", i)prints one digit, so it returns 1.j prints (j>=1) & 1 count i after -2 0 0 & 1 = 0 0 1 -1 1 0 0 2 0 2 0 0 3 1 3 1 & 1 = 1 1 4 2 4 1 3 5 - After the loop:
count += i→ 3 + 5 = 8, printed straight after the digits. - Answer:
012348. The key's348is what&&would print, since it would skip theprintfwhilej < 1. Compiled with clang, the program prints012348.
Check yourself: the same paper's Q2b has if ((y>=0) & (x=x+1)) z = z + x; for y from −3 to 3, then z = z + y. The key says 14. What's right?
x goes up on every pass: 1, 2, …, 7. The condition is (y>=0) & x, which is 1 only when y >= 0 and x is odd (bitwise with 1). That happens at y = 1 (x = 5) and y = 3 (x = 7), so z = 12. After the loop y = 4, so z = 16. The key's 14 is the && answer.
Classic traps: the standard ways marks are lost
| The mistake | What happens | The fix |
|---|---|---|
Reading & as && | You skip a side effect that really happens, or treat 1 & 4 as true. It cost the 2025 key two answers | Circle every single & before tracing |
Running the skipped side of &&/|| | A ++ that never happened gets counted | Decide the left side first; ask "is it already decided?" |
| Integer division too early | 3/4*2 = 0; an average truncated | Left to right; cast before dividing |
x % 2 == 1 as the odd test | Fails for negative odd numbers | x % 2 != 0 |
| Forgetting fall-through | You stop at the first matching case | Run downwards until break or } |
Treating default position as meaningful | You run default because it's written first | default only runs when nothing matches |
scanf width ignored | You read 1234 into a %2d | Width = maximum characters; move a cursor through the input |
Literal in the format ("%d-%d") | You assume the second value is read | A mismatch stops scanf; the later variables keep their old values |
Wrong type letter (%f for double in scanf, %lf for long double) | Garbage values; clang warns format specifies type 'double *' but the argument has type 'long double *' | %f float · %lf double · %Lf long double |
Dangling else trusted to indentation | Wrong branch; clang: add explicit braces to avoid dangling else | Pair with the nearest unmatched if; in your own code, always brace |
= for == | The condition is the assigned value | clang warns using the result of an assignment as a condition without parentheses |
Missing a char declaration in a "write the declarations" question | Lost marks (the 2025 Q4d key itself omits char grade = 'B';) | Tick off every variable the spec names |
|| where && is needed in a two-array loop | Reads past the shorter array (2024 P2 Q8 accepted both, but only && is safe) | "Both still have data" is && |
Minimal prerequisite kit
The complete list of school-level facts this page leans on:
| Fact | Where it appears |
|---|---|
| Quotient and remainder (17 = 5 × 3 + 2) | / and %; digit tricks; odd/even |
| AND/OR truth tables (sets, logic) | &&, || and when they are decided early |
| Writing a small number in binary via powers of 2 | &, <<, bit counting; also the number-systems drill |
| Rounding to a given number of decimals | %5.2f, %.1f |
| Characters have an order (a < b < … < z) | ASCII arithmetic; "highest letter" |
Unpack this step: why & with 1 tests "odd"
An odd number's binary form ends in 1, and 1 is …0001. Bitwise AND with 1 keeps only that last bit: 5 & 1 = 1, 6 & 1 = 0. That's why the 2025 Q2b condition was true only for odd x.
What to practise
Ranked for the days before the mid-sem. The past-paper questions come first, because they're the exam's own style.
| Skill | Past-paper questions | Drill / textbook | How many |
|---|---|---|---|
Short-circuit, ++/--, precedence | 24 P1 Q1 · 25 Q2d · 26 A Q3 | Operators drill · Hanly ch. 4 "Conditions" | 3 + 1 sheet |
| Division, casts, mixed types | 24 P1 Q5 · 25 Q4c · 26 A Q5 | Hanly ch. 2 "Arithmetic Expressions" | 3 |
Single &, bits | 25 Q2b, Q2h · 26 A Q10 | Operators drill (not in Hanly ch. 2/4) | 3 |
Comma, ?: chains | 24 P1 Q3 · Q14 · 26 A Q6 · 25 Q1g | Operators drill (lecture material) | 4 |
switch fall-through, default | 24 P1 Q7 · 25 Q2i · 26 B Q2b | Hanly ch. 4 "The switch Statement" | 3 |
| Nested if / conditions | 24 P1 Q12 · 25 Q4e, Q4f · 26 B Q2a | Hanly ch. 4 "Nested if Statements and Multiple-Alternative Decisions" | 4 |
scanf/printf formats | 24 P1 Q2 · Q15 · 24 P2 Q6 · 25 Q1b · 26 A Q9 | Hanly ch. 2 "Formatting Numbers in Program Output" | 5 |
| Rewrites between constructs | 24 P2 Q1–Q5 · 25 Q4a | Write them on paper, then compile to check | 6 |
Hanly references are section titles rather than numbers, because editions renumber. The comma operator, bitwise & and much of ?: aren't in ch. 2/4 at all: they come from lectures and the past papers.
Don't memorise C's full precedence table (all 15 levels) or go hunting through "C puzzle" books. The papers use exactly the ladder in card 4, and the puzzle books are full of undefined-behaviour tricks (i++ + ++i) that no sensible examiner can mark. The past papers plus a daily drill sheet are the whole preparation.