Preprocessor, Projects and Interviews · Lesson 35 of 35
C Interview Questions and Output Puzzles
Campus tests and C interviews love "what is the output?" questions and short coding tasks. Each tests one concept from this course – integer division, sizeof, pointers, strings, operators. Here are the most common, with the real output from a compiler and the reason behind it. Cover the answer, predict, then check.
In this lesson
- Output puzzles on operators, types and loops
- Puzzles on pointers, arrays and strings
- Questions that have no correct answer (undefined behaviour)
- Theory questions to prepare
Operators and types
#include <stdio.h>
int main(void) {
printf("1) %d\n", 5 / 2 * 2); // integer division first
printf("2) %d\n", 7 % -3); // the sign follows the left operand
printf("3) %d\n", (3 > 2) > 1); // what "3 > 2 > 1" really means
printf("4) %d\n", 010 + 0x10 + 10); // octal 8 + hex 16 + 10
printf("5) %zu\n", sizeof(char) + sizeof('a')); // 'a' is an int in C
printf("6) %d\n", -1 >> 31 == -1); // implementation-defined, usually arithmetic shift
int x = 5;
printf("7) %d\n", x > 3 ? x < 10 ? 1 : 2 : 3); // nested ternary
return 0;
}
1) 4 2) 1 3) 0 4) 34 5) 5 6) 1 7) 1
| # | Why |
|---|---|
| 1 | 5 / 2 is 2 in integer arithmetic, then × 2 = 4 |
| 2 | C rounds division toward zero, so the remainder takes the sign of 7 |
| 3 | 3 > 2 > 1 is read as (3 > 2) > 1: 3 > 2 is 1, and 1 > 1 is 0 – comparisons don't chain (modern compilers warn or refuse) |
| 4 | 010 is octal (8), 0x10 is hex (16): 8 + 16 + 10 = 34 |
| 5 | sizeof(char) is 1; a character literal has type int (4 bytes) in C |
| 6 | right-shifting a negative number is implementation-defined; mainstream compilers copy the sign bit |
| 7 | x > 3 is true, then x < 10 is true → 1 |
Loops and control flow
#include <stdio.h>
int main(void) {
int i;
for (i = 0; i < 5; i++); // note the semicolon: empty loop body
printf("1) i = %d\n", i);
int count = 0;
for (int a = 1; a <= 10; a += 3) count++;
printf("2) count = %d\n", count);
int n = 0;
while (n++ < 3) { }
printf("3) n = %d\n", n); // the final failed test still increments
switch (2) {
case 1: printf("one ");
case 2: printf("two ");
case 3: printf("three "); // fall-through: no breaks
default: printf("default");
}
printf("\n");
return 0;
}
1) i = 5 2) count = 4 3) n = 4 two three default
Pointers, arrays and strings
#include <stdio.h>
#include <string.h>
int main(void) {
int a[] = {10, 20, 30, 40};
int *p = a;
printf("1) %d %d\n", *(p + 2), *p + 2); // element 2 vs value of element 0 plus 2
printf("2) %d\n", *p++); // value first, then pointer moves
printf("3) %d\n", *p);
printf("4) %td\n", &a[3] - &a[0]); // elements, not bytes
char s[] = "Hello";
printf("5) %zu %zu\n", sizeof s, strlen(s)); // array size includes '\0'
printf("6) %c\n", *(s + 1));
printf("7) %s\n", s + 2); // a string starting at index 2
char t[10] = "Hi";
printf("8) %zu %zu\n", sizeof t, strlen(t));
return 0;
}
1) 30 12 2) 10 3) 20 4) 3 5) 6 5 6) e 7) llo 8) 10 2
Functions and static
#include <stdio.h>
int counter(void) {
static int c = 0; // initialised once
return ++c;
}
int change(int x, int *y) {
x = 100; // changes only the copy
*y = 100; // changes the caller's variable
return x;
}
int f(int n) { return n <= 1 ? 1 : n + f(n - 1); }
int main(void) {
counter(); counter();
printf("1) %d\n", counter());
int a = 1, b = 1;
int copy = change(a, &b);
printf("2) a=%d b=%d copy=%d\n", a, b, copy);
printf("3) %d\n", f(4)); // 4 + 3 + 2 + 1
return 0;
}
1) 3 2) a=1 b=100 copy=100 3) 10
Questions with no correct answer
Some popular "output" questions are traps: the code has undefined behaviour, so different compilers (and optimisation levels) print different things. The professional answer is to say so and explain why:
| Code | The right answer |
|---|---|
i = i++ + ++i; | undefined – i is modified twice without sequencing |
printf("%d %d", i++, i++); | undefined – argument evaluation order is unspecified and i changes twice |
int x; printf("%d", x); | undefined – reading an uninitialised variable |
int a[3]; a[3] = 1; | undefined – out of bounds |
INT_MAX + 1 | undefined – signed overflow |
char *s = "hi"; s[0] = 'H'; | undefined – modifying a string literal |
How to answer in an interview
Name the rule ("modifying a variable twice between sequence points is undefined"), mention that compilers warn about it (-Wall, -Wsequence-point), and show the well-defined way to write what was intended. That answer impresses far more than guessing a number.
Theory questions to prepare
| Question | Key points | Lesson |
|---|---|---|
| Stages of compilation | preprocess, compile, assemble, link | chapter 1 |
| Call by value vs reference | copies vs addresses (pointers) | chapters 5, 8 |
| Static variable | lives for the whole program; static global is file-private | chapter 5 |
| Array vs pointer | decay, sizeof difference, arrays can't be reassigned | chapter 8 |
| malloc vs calloc; memory leak | uninitialised vs zeroed; unfreed memory | chapter 9 |
| Dangling, wild and NULL pointers | freed/out-of-scope, uninitialised, points nowhere | chapters 8, 9 |
| Structure vs union; padding | separate vs shared memory; alignment | chapter 10 |
| Macro vs function; const vs #define | text substitution vs type-checked code | chapters 2, 12 |
| Stack vs heap | automatic locals vs malloc'd memory | chapters 1, 9 |
Classic coding tasks
#include <stdio.h>
int count_ones(unsigned int n) { int c = 0; while (n) { n &= n - 1; c++; } return c; }
int is_power_of_two(unsigned int n) { return n && !(n & (n - 1)); }
void swap_no_temp(int *a, int *b) { if (a != b) { *a ^= *b; *b ^= *a; *a ^= *b; } }
int missing_number(const int a[], int n) { // numbers 1..n+1 with one missing
int expected = (n + 1) * (n + 2) / 2, sum = 0;
for (int i = 0; i < n; i++) sum += a[i];
return expected - sum;
}
int main(void) {
printf("ones in 29: %d\n", count_ones(29));
printf("64 power of two? %d, 96? %d\n", is_power_of_two(64), is_power_of_two(96));
int x = 3, y = 8;
swap_no_temp(&x, &y);
printf("after swap: x=%d y=%d\n", x, y);
int nums[] = {1, 2, 4, 5, 6};
printf("missing number: %d\n", missing_number(nums, 5));
return 0;
}
ones in 29: 4 64 power of two? 1, 96? 0 after swap: x=8 y=3 missing number: 3
Keep practising
- The C language basics
- Variables and data storage
- Bits and bytes
- Pointers and functions
- Dynamic memory allocation
- C coding programs and output questions
- Output-based tricky questions
- Coding: arrays, strings and patterns
Summary
- Most output puzzles test integer division, literals, precedence, sizeof, pointers or fall-through.
- For undefined-behaviour puzzles, the right answer is "undefined" – with the reason.
- Revise the theory table and practise the coding tasks until you can explain each step.
Finished this lesson?
Mark it complete to track your progress. You have reached the end of this track — well done!