Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations

Top 100 C Coding-based Predict The Output Interview Questions With Explanations

Hello guys, welcome back to our blog. In this article, we will discuss the top 100 C coding-based “predict the output” interview questions with explanations. These questions are asked commonly in all automotive and IT interviews.

Ask questions if you have any electrical,  electronics, or computer science doubts. You can also catch me on Instagram – CS Electrical & Electronics

Coding-based “Predict The Output” Interview Questions

Question 1: Pointer & Increment

#include <stdio.h>
int main() {
    int a = 10;
    int *p = &a;
    printf("%d %d %d", a, *p, *p++);
    return 0;
}

Output:

10 10 10

Explanation:

  • *p++ is equivalent to *(p++), so it returns the value at p before incrementing it.
  • But since p is not used later, its increment doesn’t affect the rest.
  • So: a = 10, *p = 10, *p++ = 10.

Question 2: Static Variable

#include <stdio.h>
void func() {
    static int x = 0;
    x++;
    printf("%d ", x);
}
int main() {
    func();
    func();
    func();
    return 0;
}

Output:

1 2 3

Explanation:

  • static int x retains its value across function calls.
  • Each time func() is called, x is incremented and printed.

Question 3: String and Array

#include <stdio.h>
int main() {
    char str[] = "Hello";
    str[0] = 'Y';
    printf("%s", str);
    return 0;
}

Output:

Yello

Explanation:

  • char str[] = “Hello” creates a modifiable array.
  • You can change individual characters.
  • str[0] = ‘Y’; changes “Hello” to “Yello”.

Question 4: Array Index

#include <stdio.h>
int main() {
    int arr[] = {10, 20, 30, 40};
    printf("%d", 2[arr]);
    return 0;
}

Output:

30

Explanation:

  • 2[arr] is same as arr[2]. It’s valid due to how pointer arithmetic works.
  • So it prints the 3rd element → 30.

Question 5: Pre/Post-Increment

#include <stdio.h>
int main() {
    int x = 5;
    int y = x++ + ++x;
    printf("%d %d", x, y);
    return 0;
}

Output:

7 12

Explanation:

  • x++ is 5 (post-increment), ++x becomes 7.
  • So: y = 5 + 7 = 12, and finally x = 7.

Question 6: sizeof and Array

#include <stdio.h>
int main() {
    int arr[10];
    printf("%d", sizeof(arr) / sizeof(arr[0]));
    return 0;
}

Output:

10

Explanation:

  • sizeof(arr) gives the total bytes.
  • sizeof(arr[0]) gives bytes of one element.
  • Their division gives the number of elements → 10.

Question 7: Null Terminator

#include <stdio.h>
int main() {
    char str[5] = {'H','e','l','l','o'};
    printf("%s", str);
    return 0;
}

Ouput:

Hellox (or garbage after o)

Explanation:

  • There’s no null character (\0) at the end.
  • printf(“%s”, str); expects a null-terminated string.
  • Output may include garbage after “Hello”.

Question 8: Recursion

#include <stdio.h>
int fun(int n) {
    if(n == 0)
        return 0;
    return n + fun(n - 1);
}
int main() {
    printf("%d", fun(5));
    return 0;
}

Output:

15

Explanation:

  • It’s the sum of the first 5 natural numbers: 5+4+3+2+1+0 = 15

Question 9: Pointer Confusion

#include &lt;stdio.h>
int main() {
    int a = 10;
    int *p = &amp;a;
    int **q = &amp;p;
    **q = 20;
    printf("%d", a);
    return 0;
}

Output:

20

Explanation:

  • *p refers to a. **q also refers to a.
  • So **q = 20 means a = 20.
  • **q: A double pointer is a pointer that stores the address of another pointer.

Question 10: Function Return and Comma Operator

#include <stdio.h>
int fun() {
    return (1, 2, 3);
}
int main() {
    printf("%d", fun());
    return 0;
}

Output:

3

Explanation:

  • The comma operator evaluates all expressions but returns the last one.
  • So fun() returns 3.

Question 11: Const Pointer

#include <stdio.h>
int main() {
    int x = 10, y = 20;
    const int *p = &x;
    //*p = 30; // Invalid
    p = &y;
    printf("%d", *p);
    return 0;
}

Output:

20

Explanation:

  • const int *p means the value at p is constant, but p itself can point to another variable.
  • So you can do p = &y;, but not *p = something.

Question 12: Post Increment in Print

#include <stdio.h>
int main() {
    int x = 5;
    printf("%d %d %d", x, x++, ++x);
    return 0;
}

Output:

Undefined behavior

Explanation:

  • Modifying a variable more than once without a sequence point (like in x++, ++x) leads to undefined behavior.
  • The output may differ between compilers. Avoid in real-world code.

Question 13: Array Out of Bounds

#include <stdio.h>
int main() {
    int arr[3] = {1, 2, 3};
    printf("%d", arr[5]);
    return 0;
}

Output:

Garbage value (or crash)

Explanation:

  • Accessing arr[5] is out-of-bounds.
  • It doesn’t always crash, but the result is undefined.

Question 14: String Literal Modification

#include <stdio.h>
int main() {
    char *str = "Hello";
    str[0] = 'Y';
    printf("%s", str);
    return 0;
}

Output:

Runtime Error / Segmentation Fault

Explanation:

  • String literals are stored in read-only memory.
  • Modifying them leads to crashes. Always use char str[] = “Hello” if you want to change it.

Question 15: Infinite Loop

#include <stdio.h>
int main() {
    int i = 0;
    while (i < 3)
        printf("Hi\n");
    return 0;
}

Output:

Hi
Hi
Hi
... (infinite)

Explanation:

  • i is never incremented, so condition i < 3 always holds true.
  • Infinite loop.

Question 16: Enum Basics

#include <stdio.h>
enum Days { MON, TUE = 5, WED, THU };
int main() {
    printf("%d %d %d", MON, WED, THU);
    return 0;
}

Output:

0 6 7

Explanation:

  • MON = 0 by default
  • TUE = 5, so WED = 6, THU = 7

Question 17: Void Pointer Arithmetic

#include <stdio.h>
int main() {
    void *ptr;
    int x = 10;
    ptr = &x;
    ptr++;  // Invalid
    return 0;
}

Output:

Compilation Error

Explanation:

  • You cannot perform arithmetic on void pointers because the compiler doesn’t know the size of the object.

Question 18: main With Parameters

#include <stdio.h>
int main(int argc, char *argv[]) {
    printf("%d", argc);
    return 0;
}

Output:

1

Explanation:

  • argc holds the count of arguments. The program name counts as one.

Question 19: Structure Memory Layout

#include <stdio.h>
struct test {
    int x;
    char y;
    float z;
};
int main() {
    struct test t;
    printf("%lu", sizeof(t));
    return 0;
}

Output:

12 (or 16 depending on padding)

Explanation:

  • Padding is added to align memory (usually 4 or 8 bytes alignment).
  • The actual size depends on the compiler/platform (use pragma pack() to control padding).

Question 20: Union Behavior

#include <stdio.h>
union data {
    int i;
    float f;
};
int main() {
    union data d;
    d.i = 10;
    d.f = 3.14;
    printf("%d", d.i);
    return 0;
}

Output:

Garbage value

Explanation:

  • In a union, all members share the same memory.
  • Writing to f overwrites the memory of I.

Question 21: Dynamic Memory and Free

#include <stdio.h>
#include <stdlib.h>
int main() {
    int *p = (int *)malloc(sizeof(int));
    *p = 100;
    free(p);
    printf("%d", *p);
    return 0;
}

Output:

Undefined (could be garbage or crash)

Explanation:

  • Accessing memory after free() is undefined behavior.
  • It might work, crash, or give garbage.

Question 22: Recursion with Static

#include <stdio.h>
void func() {
    static int x = 5;
    if (--x)
        func();
    printf("%d ", x);
}
int main() {
    func();
    return 0;
}

Output:

0 0 0 0

Explanation:

  • x is static, initialized once.
  • Each recursive call decrements it.
  • After x == 0, prints 0 on return from each call.

Question 23: Bitwise Operators

#include <stdio.h>
int main() {
    int a = 5;
    int b = 9;
    printf("%d", a & b);
    return 0;
}

Output:

1

Explanation:

  • 5 = 0101, 9 = 1001
  • Bitwise AND: 0001 = 1

Question 24: Nested Structure

#include <stdio.h>
struct inner {
    int x;
};
struct outer {
    struct inner in;
};
int main() {
    struct outer o;
    o.in.x = 25;
    printf("%d", o.in.x);
    return 0;
}

Output:

25

Explanation:

  • Shows nested structure access via outer.inner.member.

Question 25: Character Arithmetic

#include <stdio.h>
int main() {
    char a = 'A';
    a += 5;
    printf("%c", a);
    return 0;
}

Output:

F

Explanation:

  • ‘A’ = 65, so 65 + 5 = 70 = ‘F’.

Question 26: Pointer to Array

#include <stdio.h>
int main() {
    int arr[] = {1, 2, 3, 4};
    int (*p)[4] = &arr;
    printf("%d", (*p)[2]);
    return 0;
}

Output:

3

Explanation:

  • p is a pointer to an array of 4 integers.
  • So (*p)[2] accesses the 3rd element.

Question 27: Ternary Confusion

#include <stdio.h>
int main() {
    int a = 5, b = 10;
    int c = a > b ? a : b > 15 ? b : 0;
    printf("%d", c);
    return 0;
}

Output:

0

Explanation:

  • a > b is false → move to b > 15 ? b : 0
  • b > 15 is also false → return 0

Question 28: Sizeof with Pointer

#include <stdio.h>
int main() {
    int arr[10];
    int *ptr = arr;
    printf("%lu %lu", sizeof(arr), sizeof(ptr));
    return 0;
}

Output:

40 8

Explanation:

  • sizeof(arr) = 10 * 4 = 40
  • sizeof(ptr) = size of pointer (usually 8 bytes on 64-bit system)

Question 29: Macro Expansion Surprise

#include <stdio.h>
#define SQUARE(x) x * x

int main() {
    int a = 3;
    printf("%d", SQUARE(a + 1));
    return 0;
}

Output:

7

Explanation:

  • Macro expands to: a + 1 * a + 1 → 3 + 1 * 3 + 1 → 3 + 3 + 1 = 7
  • Should have been #define SQUARE(x) ((x)*(x))

Question 30: Const Puzzle

#include <stdio.h>
int main() {
    const int x = 10;
    int *p = (int*)&x;
    *p = 20;
    printf("%d", x);
    return 0;
}

Output:

10 or 20 (undefined behavior)

Explanation:

  • Modifying a const variable through a pointer is undefined behavior.
  • Some compilers may show 10, others may reflect modified memory as 20.

Question 31: Volatile Trick

#include <stdio.h>
int main() {
    volatile int x = 10;
    int *p = (int *)&x;
    *p = 20;
    printf("%d", x);
    return 0;
}

Output:

20

Explanation:

  • Volatile tells the compiler not to optimize access.
  • But if x is changed via a pointer, that change reflects because it’s still the same memory.

Question 32: Infinite Recursion Without Base Case

#include <stdio.h>
void foo() {
    printf("Hi ");
    foo();
}
int main() {
    foo();
    return 0;
}

Output:

Hi Hi Hi... (stack overflow eventually)

Explanation:

  • Infinite recursion without stopping condition → leads to stack overflow crash.

Question 33: String and Character

#include <stdio.h>
int main() {
    char *s = "A";
    printf("%d", sizeof(s));
    return 0;
}

Output:

8

Explanation:

  • s is a pointer to a string → sizeof(s) gives the size of the pointer, not the string length.

Question 34: Array vs Pointer Confusion

#include &lt;stdio.h>
int main() {
    int a[] = {1, 2, 3};
    int *p = a;
    printf("%d", *(p + 2));
    return 0;
}

Output:

3

Explanation:

  • Pointer arithmetic: *(p + 2) accesses the third element.

Question 35: Nested Ternary

#include <stdio.h>
int main() {
    int a = 5;
    int b = 10;
    int c = 15;
    int result = a > b ? a : b > c ? b : c;
    printf("%d", result);
    return 0;
}

Output:

15

Explanation:

  • a > b is false → move to b > c ? b : c
  • b > c is false → result is c = 15

Question 36: Assignment in Condition

#include <stdio.h>
int main() {
    int x = 0;
    if (x = 5)
        printf("True");
    else
        printf("False");
    return 0;
}

Output:

True

Explanation:

  • Mistakenly used = instead of ==
  • x = 5 evaluates to 5 → treated as true

Question 37: Macro with Side Effects

#include <stdio.h>
#define INCREMENT(x) x+1
int main() {
    int a = 5;
    printf("%d", INCREMENT(a) * INCREMENT(a));
    return 0;
}

Output:

36

Explanation:

Let’s break it down properly:

  • INCREMENT(a) → a+1
  • So INCREMENT(a) * INCREMENT(a) → (a+1)*(a+1) → 6 * 6 = 36 ✅
  • But macro has no parentheses: a+1 * a+1 = a + (1 * a) + 1 = 5 + 5 + 1 = 11
  • ✅ Final Output: 11

➡️ Fix macro with parentheses: #define INCREMENT(x) ((x)+1)

Question 38: Character Array With No Null-Terminator

#include <stdio.h>
int main() {
    char str[4] = {'H', 'e', 'l', 'o'};
    printf("%s", str);
    return 0;
}

Output:

Garbage after "Helo" or crash

Explanation:

  • No ‘\0’ → leads to undefined behavior while printing a string.

Question 39: Toggle Bit

#include <stdio.h>
int main() {
    int x = 9;   // 1001
    x = x ^ (1 << 0); // Toggle LSB
    printf("%d", x);
    return 0;
}

Output:

8

Explanation:

  • LSB toggled from 1 to 0 → 1000 → decimal 8

Question 40: Swap Using XOR

#include <stdio.h>
int main() {
    int a = 5, b = 9;
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    printf("%d %d", a, b);
    return 0;
}

Output:

9 5

Explanation:

  • Classic XOR swap trick

Question 41: Signed vs Unsign

#include <stdio.h>
int main() {
    unsigned int a = 10;
    int b = -42;
    if (a > b)
        printf("Yes");
    else
        printf("No");
    return 0;
}

Output:

No

Explanation:

  • b is converted to unsigned → becomes a large positive number due to 2’s complement
  • Actually: 10 > 4294967254 → false

Question 42: Infinite Loop Without Braces

#include <stdio.h>
int main() {
    int i = 0;
    while (i < 3)
        printf("Hi\n");
        i++;
    return 0;
}

Output:

Infinite Hi (or compilation warning)

Explanation:

  • Only printf is inside loop, i++ is outside → infinite loop

Question 43: Char Signedness

#include <stdio.h>
int main() {
    char c = 255;
    printf("%d", c);
    return 0;
}

Output:

-1 (on most systems)

Explanation:

  • char is signed by default → 255 = -1 (two’s complement)

Question 44: Bitwise NOT on Unsigned

#include <stdio.h>
int main() {
    unsigned int a = 0;
    printf("%u", ~a);
    return 0;
}

Output:

4294967295

Explanation:

  • ~0 in 32-bit unsigned is all 1s → max value for unsigned int (2³² – 1)

Question 45: Function Return Trap

#include <stdio.h>
int* get() {
    int x = 10;
    return &x;
}
int main() {
    int *ptr = get();
    printf("%d", *ptr);
    return 0;
}

Output:

Garbage value / Segfault

Explanation:

  • Returning address of local variable → invalid memory

Question 46: Floating Point Comparison

#include <stdio.h>
int main() {
    float a = 0.1;
    if (a == 0.1)
        printf("Equal");
    else
        printf("Not Equal");
    return 0;
}

Output:

Not Equal

Explanation:

  • 0.1 is double, a is float → precision loss during comparison

Question 47: Pointer to Function + Array

#include <stdio.h>
void fun1() { printf("A "); }
void fun2() { printf("B "); }

int main() {
    void (*arr[2])() = {fun1, fun2};
    for(int i = 0; i < 2; i++)
        (*arr[i])();
    return 0;
}

Output:

A B

Explanation:

  • Array of function pointers, calling them like regular functions.

Question 48: Sizeof vs strlen

#include &lt;stdio.h>
int main() {
    char str[] = "ABC";
    printf("%lu %lu", sizeof(str), strlen(str));
    return 0;
}

Output:

4 3

Explanation:

  • sizeof includes ‘\0’ in a string literal.
  • strlen does not include the null character.

Question 49: Function Pointer Array with Logic

#include <stdio.h>

void add(int x, int y) { printf("Sum: %d\n", x + y); }
void mul(int x, int y) { printf("Product: %d\n", x * y); }

int main() {
    void (*fp[2])(int, int) = {add, mul};
    fp[1](3, 4);  // mul
    fp[0](3, 4);  // add
    return 0;
}

Output:

Product: 12  
Sum: 7

Explanation:

  • Arrays of function pointers behave like regular arrays, and can be indexed/called directly.

Question 50: Sizeof Void Pointer

#include <stdio.h>
int main() {
    void *ptr;
    printf("%lu", sizeof(ptr));
    return 0;
}

Output:

8

Explanation:

  • sizeof(void*) gives the size of pointer (not of what it points to), typically 8 bytes on 64-bit.

Question 51: Pointer Difference

#include <stdio.h>int main() {
    int arr[] = {10,20,30,40};
    int *p1 = &arr[1];
    int *p2 = &arr[3];    printf("%ld", p2 - p1);    return 0;
}

Output

2

Explanation

Pointer subtraction returns the number of elements between two addresses.

p2 → arr[3]
p1 → arr[1]Difference = 3 - 1 = 2

Question 52: Register Variable Address

#include <stdio.h>
int main() {    
   register int x = 10;    
   int *p = &x;    
   printf("%d", *p);    
   return 0;
}

Output

Compilation Error

Explanation

register variables may be stored in CPU registers instead of memory.

Because registers do not have a memory address, using:

&x

may cause a compilation error.


Question 53: Bit Shift Trick

#include <stdio.h>
int main() {    
   int x = 5;    
   printf("%d", x << 1);    
   return 0;
}

Output

10

Explanation

Left shift multiplies by 2ⁿ.

5 = 0101
5 << 1 = 1010 = 10

Question 54: Array Decay in Function

#include <stdio.h>
void fun(int arr[]) {
    printf("%lu", sizeof(arr));
}

int main() {    
    int arr[10];    
    printf("%lu ", sizeof(arr));
    fun(arr);    
    return 0;
}

Output (64-bit)

40 8

Explanation

In function parameters:

int arr[]

is treated as

int *arr

So:

sizeof(arr) in main = 40
sizeof(arr) in function = pointer size = 8


Question 55: Static Variable Inside Recursion

#include <stdio.h>void fun() {    
static int x = 3;    
if(x-- > 0) {
        fun();
        printf("%d ", x);
    }}

int main() {    
   fun();    
   return 0;
}

Output

-1 -1 -1

Explanation

Static variable keeps the same memory during recursion.

Execution:

x = 3 → 2 → 1 → 0

When recursion returns, x becomes -1 and prints.


Question 56: Comma Operator

#include <stdio.h>
int main() {    
    int x = (10, 20, 30);    
    printf("%d", x);    
    return 0;
}

Output

30

Explanation

Comma operator evaluates all expressions but returns the last value.

x = 30

Question 57: Character Pointer Increment

#include <stdio.h>
int main() {    
    char str[] = "HELLO";    
    char *p = str;    
    printf("%c ", *p++);
    printf("%c ", *p);
}

Output

H E

Explanation

*p++  → prints H then pointer moves
*p → now points to E

Question 58: Bitwise XOR Property

#include <stdio.h>int main() {    
    int x = 7;    
    printf("%d", x ^ x);    
    return 0;
}

Output

0

Explanation

XOR rule:

A ^ A = 0

Used in encryption and error detection algorithms.


Question 59: Enum Increment

#include <stdio.h>
enum num {A = 3, B, C};
int main() {    
    printf("%d %d %d", A, B, C);    
    return 0;
}

Output

3 4 5

Explanation

Enums auto-increment.

A = 3
B = 4
C = 5

Question 60: Logical Operators

#include <stdio.h>
int main() {    
    int x = 0;    
    if(x && printf("Hello"))
        printf("World");    
    return 0;
}

Output

(no output)

Explanation

Logical AND (&&) uses short-circuit evaluation.

Since x = 0:

x && something

Second expression is not executed, so nothing prints.

Question 61: Post Increment in Function Argument

#include <stdio.h>
int fun(int x) {
    return x++;
}

int main() {    
    int a = 5;    
    printf("%d %d", fun(a), a);    
    return 0;
}

Output

5 5

Explanation

a is passed by value, not by reference.

Steps:

fun(a)
x = 5
return x++ → returns 5

a in main() does not change.

So output:

5 5

Question 62: Pre vs Post Increment

#include <stdio.h>
int main() {    
   int x = 5;    
   printf("%d %d %d", x, x++, ++x);    
   return 0;
}

Output

Undefined Behavior

Explanation

The variable x is modified multiple times in the same statement without sequence points.

x++
++x

Order of evaluation is not guaranteed in C, so the result is undefined.

Interviewers use this to test knowledge of sequence points.


Question 63: Sizeof with Increment

#include <stdio.h>
int main() {    
    int x = 10;    
    printf("%lu %d", sizeof(x++), x);    
    return 0;
}

Output

4 10

(4 may be 8 depending on system)

Explanation

sizeof does not evaluate the expression.

sizeof(x++)

Compiler only checks the type of x, not the expression.

So:

x is NOT incremented

Question 64: Nested Ternary Operator

#include <stdio.h>
int main() {    
    int a = 5, b = 10;    
    int result = (a > b) ? a : (b > 15 ? b : 20);    
    printf("%d", result);    
    return 0;
}

Output

20

Explanation

First condition:

a > b → false

Second condition:

b > 15 → false

So result becomes:

20

Question 65: Logical OR Short Circuit

#include <stdio.h>
int main() {    
int x = 1;    
if(x || printf("Hello"))
        printf("World");    
return 0;
}

Output

World

Explanation

Logical OR (||) stops when first condition is true.

x = 1 → true

So:

printf("Hello")

is never executed.

Only:

World

prints.


Question 66: Character Arithmetic

#include <stdio.h>
int main() {
    char c = 'A';
    printf("%d", c + 3);
    return 0;
}

Output

68

Explanation

ASCII value of 'A':

65

So:

65 + 3 = 68

Question 67: Assignment in Condition

#include <stdio.h>
int main() {
    int x = 0;
    if(x = 5)
        printf("True");
    else
        printf("False");
    return 0;
}

Output

True

Explanation

This is assignment, not comparison.

x = 5

Value of assignment expression = 5

Since 5 is non-zero, condition becomes true.


Question 68: Double Negation

#include <stdio.h>
int main() {
    int x = 5;
    printf("%d", !!x);
    return 0;
}

Output

1

Explanation

!x  → 0
!!x → 1

Double negation converts any non-zero value into 1.

Used often in Boolean conversions.


Question 69: Modulus with Negative Number

#include <stdio.h>
int main() {
    printf("%d", -10 % 3);
    return 0;
}

Output

-1

Explanation

In C, modulus keeps the sign of the dividend.

-10 / 3 = -3 remainder -1

Question 70: Switch Case Without Break

#include <stdio.h>
int main() {
    int x = 2;
    switch(x) {
        case 1:
            printf("A");
        case 2:
            printf("B");
        case 3:
            printf("C");
    }    
return 0;
}

Output

BC

Explanation

switch executes all cases after a match until break appears.

Execution:

case 2 → B
case 3 → C

So output:

BC

Question 71: Circular Buffer (DSA used in Embedded Systems)

#include <stdio.h>
#define SIZE 5int buffer[SIZE];
int head = 0;
int tail = 0;

void enqueue(int data) {
    buffer[tail] = data;
    tail = (tail + 1) % SIZE;
}

void printBuffer() {
    for(int i = 0; i < SIZE; i++)
        printf("%d ", buffer[i]);
}

int main() {
    enqueue(10);
    enqueue(20);
    enqueue(30);
    enqueue(40);
    enqueue(50);
    enqueue(60);
    printBuffer();
    return 0;
}

Output

60 20 30 40 50

Explanation

Circular buffers are heavily used in UART, SPI, and RTOS queues.

tail = (tail + 1) % SIZE

When buffer reaches the end, it wraps around to index 0, overwriting old data.


Question 72: Stack Implementation Using Array

#include <stdio.h>
#define SIZE 5int stack[SIZE];

int top = -1;
void push(int x) {
    stack[++top] = x;
}

int pop() {
    return stack[top--];
}

int main() {
    push(10);
    push(20);
    push(30);
    printf("%d ", pop());
    printf("%d ", pop());
    return 0;
}

Output

30 20

Explanation

Stack follows LIFO (Last In First Out).

Push: 10 20 30
Pop → 30
Pop → 20

Stacks are used in:

  • Function calls
  • Interrupt handling
  • RTOS task context switching

Question 73: Linked List Traversal

#include <stdio.h>
#include <stdlib.h>
struct Node {
    int data;
    struct Node* next;
};

int main() {
    struct Node *head = malloc(sizeof(struct Node));
    struct Node *second = malloc(sizeof(struct Node));
    struct Node *third = malloc(sizeof(struct Node));
    head->data = 10;
    head->next = second;
    second->data = 20;
    second->next = third;
    third->data = 30;
    third->next = NULL;
    struct Node *temp = head;
    while(temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    return 0;
}

Output

10 20 30

Explanation

Linked lists are used in embedded systems for:

  • Dynamic task lists
  • Timer queues
  • Memory management

Traversal continues until NULL.


Question 74: Priority Queue Logic

#include <stdio.h>
int main() {
    int priority[] = {3,1,4,2};
    int size = 4;
    int highest = 0;
    for(int i = 1; i < size; i++) {
        if(priority[i] > priority[highest])
            highest = i;
    }
    printf("%d", priority[highest]);
    return 0;
}

Output

4

Explanation

Priority scheduling is used in RTOS task scheduling.

Here the program finds the highest priority task.


Question 75: RTOS Task Simulation

#include <stdio.h>

void task1() {
    printf("Task1 ");
}

void task2() {
    printf("Task2 ");
}

int main() {
    void (*scheduler[2])() = {task1, task2};
    scheduler[0]();
    scheduler[1]();
    return 0;
}

Output

Task1 Task2

Explanation

RTOS kernels often store task functions in arrays of function pointers.

void (*scheduler[])()

This acts like a very simple task scheduler.


Question 76: Bit Manipulation (Set Bit)

#include <stdio.h>
int main() {
    int num = 8;
    num = num | (1 << 1);
    printf("%d", num);
    return 0;
}

Output

10

Explanation

8 = 1000
1<<1 = 0010

OR operation:

1000
0010
----
1010 = 10

Bit operations are widely used in GPIO registers and hardware control.


Question 77: RTOS Delay Simulation

#include <stdio.h>int main()
 {    int tick = 0;
    while(tick < 3) {
        printf("Task running\n");
        tick++;
    }
    return 0;
}

Output

Task running
Task running
Task running

Explanation

RTOS uses system ticks for timing.

Example:

vTaskDelay(3)

would delay a task for 3 scheduler ticks.


Question 78: Queue Implementation (Embedded IPC)

#include <stdio.h>
#define SIZE 3int queue[SIZE];
int front = -1, rear = -1;void enqueue(int x) {
    if(front == -1) front = 0;
    rear++;
    queue[rear] = x;
}

int dequeue() {
    return queue[front++];
}

int main() {
    enqueue(5);
    enqueue(10);
    enqueue(15);
    printf("%d ", dequeue());
    printf("%d ", dequeue());
    return 0;
}

Output

5 10

Explanation

Queues are used in RTOS for:

  • Task communication
  • Message passing
  • ISR to task communication

Question 79: Toggle Bit

#include <stdio.h>
int main() {
    int x = 10;
    x = x ^ (1 << 1);
    printf("%d", x);
    return 0;
}

Output

8

Explanation

10 = 1010
1<<1 = 0010

XOR toggles the bit:

1010
0010
----
1000 = 8

Question 80: Simple Task State Machine

#include <stdio.h>
int main() {
    int state = 0;
    for(int i = 0; i < 3; i++) {
        if(state == 0) {
            printf("INIT ");
            state = 1;
        }
        else if(state == 1) {
            printf("RUN ");
            state = 2;
        }
        else {
            printf("STOP ");
        }
    }
    return 0;
}

Output

INIT RUN STOP

Explanation

State machines are widely used in embedded firmware.

Typical states:

INIT → RUN → STOP

Used in:

  • communication protocols
  • motor control
  • embedded drivers

Question 81: Binary Search (DSA for Embedded Optimization)

#include <stdio.h>
int binarySearch(int arr[], int size, int key) {
    int low = 0, high = size - 1;
    while(low <= high) {
        int mid = (low + high) / 2;
        if(arr[mid] == key)
            return mid;
        else if(arr[mid] < key)
            low = mid + 1;
        else
            high = mid - 1;
    }
    return -1;
}

int main() {
    int arr[] = {2,4,6,8,10,12};
    int index = binarySearch(arr, 6, 8);
    printf("%d", index);
    return 0;
}

Output

3

Explanation

Binary search is a very efficient searching algorithm used when the data is already sorted.

Instead of checking every element one by one (like linear search), binary search repeatedly divides the array into two halves and checks the middle element.

Steps in this example:

Array: 2 4 6 8 10 12
Key = 8
  1. low = 0, high = 5
  2. mid = (0 + 5)/2 = 2 → value = 6
  3. Since 8 > 6, search the right half
  4. Now low = 3, high = 5
  5. mid = 4 → value = 10
  6. Since 8 < 10, search the left half
  7. mid = 3 → value = 8 (found)

Index returned is 3.

Binary search is widely used in embedded firmware for:

  • Searching lookup tables
  • Sensor calibration tables
  • Fast configuration lookups

Time complexity:

O(log n)

which is much faster than linear search for large datasets.


Question 82: Counting Set Bits (Bit Manipulation)

#include <stdio.h>
int main() {
    int num = 13;
    int count = 0;
    while(num) {
        count += num & 1;
        num = num >> 1;
    }
    printf("%d", count);
    return 0;
}

Output

3

Explanation

This program counts the number of set bits (1s) in the binary representation of a number.

Binary of 13:

13 = 1101

There are three 1s, so the output is 3.

How the algorithm works:

  1. num & 1 checks whether the least significant bit is 1
  2. If it is 1, we increment the counter
  3. Then we right shift the number

Example:

1101 → 110 → 11 → 1 → 0

This technique is used frequently in embedded systems for:

  • Status register checks
  • Flag counting
  • Bitmask operations
  • Error detection

Bit operations are extremely important in embedded firmware because hardware registers are controlled using bits.


Question 83: Simple Task Scheduler Logic

#include <stdio.h>
void task1() { printf("Sensor Read\n"); }
void task2() { printf("Data Process\n"); }
void task3() { printf("Send Data\n"); }

int main() {
    void (*tasks[3])() = {task1, task2, task3};
    for(int i = 0; i < 3; i++)
        tasks[i]();
    return 0;
}

Output

Sensor Read
Data Process
Send Data

Explanation

This program demonstrates a very simple scheduler concept used in embedded firmware and RTOS systems.

Instead of calling tasks directly, we store their function addresses inside an array of function pointers.

void (*tasks[3])()

This means:

tasks[0] → task1
tasks[1] → task2
tasks[2] → task3

The scheduler simply loops through the array and executes each task.

Real embedded systems use a similar concept for:

  • RTOS task scheduling
  • Interrupt vector tables
  • Callback handlers
  • Driver abstraction layers

Using function pointers allows the firmware to be modular and scalable.


Question 84: Finding Maximum Element (DSA Logic)

#include <stdio.h>
int main() {
    int arr[] = {12, 45, 7, 89, 34};
    int max = arr[0];
    for(int i = 1; i < 5; i++) {
        if(arr[i] > max)
            max = arr[i];
    }
    printf("%d", max);
    return 0;
}

Output

89

Explanation

This program finds the maximum element in an array.

Steps:

  1. Assume the first element is the maximum
max = 12
  1. Compare with each element:
45 > 12 → max = 45
7 < 45 → ignore
89 > 45 → max = 89
34 < 89 → ignore

Final maximum value:

89

This logic is used in embedded applications like:

  • Finding maximum sensor reading
  • Peak detection
  • Signal processing
  • ADC sampling analysis

Even though the algorithm is simple, it is commonly used in real firmware code.


Question 85: Priority-Based Task Selection (RTOS Concept)

#include <stdio.h>
int main() {
    int priority[] = {2,5,1,4};
    int highest = 0;
    for(int i = 1; i < 4; i++) {
        if(priority[i] > priority[highest])
            highest = i;
    }
    printf("Task %d will run", highest);
    return 0;
}

Output

Task 1 will run

Explanation

In many RTOS systems, tasks are scheduled based on priority.

Higher priority tasks get CPU time before lower priority tasks.

Here the program scans the priority array:

priority = {2,5,1,4}

The highest value is:

5

which belongs to Task 1.

Therefore the scheduler selects:

Task 1

In real RTOS systems such as FreeRTOS, the scheduler constantly checks which task has the highest priority in the ready state and runs that task.

Priority-based scheduling is important for:

  • Real-time deadlines
  • Interrupt handling
  • Time-critical tasks like motor control

Question 86: Reverse an Array (Common Embedded Logic)

#include <stdio.h>
int main() {
    int arr[] = {1,2,3,4,5};
    int n = 5;
    for(int i = n-1; i >= 0; i--)
        printf("%d ", arr[i]);
    return 0;
}

Output

5 4 3 2 1

Explanation

This program prints the array in reverse order.

Instead of starting from index 0, we start from:

n - 1

which is the last element.

Execution order:

5 → 4 → 3 → 2 → 1

Array reversal is used in embedded applications such as:

  • Signal processing
  • Data buffering
  • Packet parsing
  • Communication protocols

Sometimes data arrives in reverse byte order (endianness issues), so reversing arrays becomes necessary.

Question 87: Producer–Consumer Buffer Logic (RTOS Concept)

#include <stdio.h>#define SIZE 3int buffer[SIZE];

int count = 0;void produce(int data) {
    if(count < SIZE) {
        buffer[count++] = data;
    }
}

int consume() {
    if(count > 0)
        return buffer[--count];
    return -1;
}

int main() {
    produce(10);
    produce(20);
    produce(30);
    printf("%d ", consume());
    printf("%d ", consume());
    return 0;
}

Output

30 20

Explanation

This program demonstrates a simplified producer–consumer model, which is a classic synchronization problem in RTOS and concurrent systems.

The idea:

  • Producer task adds data to the buffer
  • Consumer task removes data from the buffer

Here the buffer behaves like a stack because consumption occurs from the last inserted element.

Execution flow:

Produce → 10
Produce → 20
Produce → 30
Buffer = {10,20,30}

Now consuming:

Consume → 30
Consume → 20

In real RTOS systems like FreeRTOS, this problem is solved using:

  • Queues
  • Semaphores
  • Mutexes

These mechanisms ensure that multiple tasks safely share the same buffer without data corruption.


Question 88: Semaphore Simulation

#include <stdio.h>
int semaphore = 1;
void accessResource() {
    if(semaphore == 1) {
        semaphore = 0;
        printf("Resource Accessed\n");
        semaphore = 1;
    }
    else {
        printf("Resource Busy\n");
    }
}

int main() {
    accessResource();
    accessResource();
    return 0;
}

Output

Resource Accessed
Resource Accessed

Explanation

This code simulates the concept of a binary semaphore, which is widely used in RTOS systems to protect shared resources.

A semaphore acts like a lock mechanism.

1 → resource available
0 → resource locked

Execution:

  1. First call
    • semaphore = 1
    • resource accessed
    • semaphore temporarily becomes 0
  2. After access completes
    • semaphore becomes 1 again

So the second call also succeeds.

In real embedded systems, semaphores are used to protect:

  • Shared peripherals (UART, SPI, I2C)
  • Shared memory buffers
  • Hardware drivers accessed by multiple tasks

Without synchronization mechanisms like semaphores, race conditions can occur.


Question 89: Circular Queue Index Logic

#include <stdio.h>
#define SIZE 4
int main() {
    int rear = 3;
    rear = (rear + 1) % SIZE;
    printf("%d", rear);
    return 0;
}

Output

0

Explanation

This example demonstrates the wrap-around logic used in circular queues, which are very common in embedded firmware.

Circular buffers are used in:

  • UART receive buffers
  • DMA buffers
  • RTOS message queues

Given:

SIZE = 4
rear = 3

When we increment:

rear + 1 = 4

Applying modulo operation:

4 % 4 = 0

So the index wraps back to the start of the buffer.

This prevents the queue from exceeding its allocated memory and allows the buffer to reuse space efficiently.


Question 90: Detect Even or Odd Using Bitwise

#include <stdio.h>int main() {
    int num = 17;
    if(num & 1)
        printf("Odd");
    else
        printf("Even");
    return 0;
}

Output

Odd

Explanation

This program checks whether a number is even or odd using a bitwise operation.

Binary representation of 17:

10001

The least significant bit (LSB) determines parity.

Even numbers → LSB = 0
Odd numbers → LSB = 1

Using:

num & 1

If the result is 1, the number is odd.

Bitwise methods are preferred in embedded systems because they are:

  • Faster than arithmetic operations
  • Low CPU overhead
  • Efficient on microcontrollers

This technique is frequently used in interrupt flags, hardware register checks, and signal processing.


Question 91: Task Round-Robin Simulation

#include <stdio.h>
int main() {
    char *tasks[] = {"T1","T2","T3"};
    for(int i=0;i<6;i++)
        printf("%s ", tasks[i%3]);
    return 0;
}

Output

T1 T2 T3 T1 T2 T3

Explanation

This example simulates a round-robin scheduling algorithm, which is commonly used in real-time operating systems.

In round-robin scheduling:

  • Each task gets equal CPU time
  • Tasks run in a cyclic order

Here we use modulo operator:

i % 3

which cycles through indices:

0 → 1 → 2 → 0 → 1 → 2

So tasks execute repeatedly:

T1 → T2 → T3 → T1 → T2 → T3

Round-robin scheduling is often used in systems where:

  • Tasks have equal priority
  • Fair CPU allocation is required
  • No strict deadline constraints exist

Question 92: Swap Two Numbers Without Temp Variable

#include <stdio.h>
int main() {
    int a = 5, b = 7;
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    printf("%d %d", a, b);
    return 0;
}

Output

7 5

Explanation

This program swaps two numbers using the XOR bitwise operation without using a temporary variable.

XOR properties used:

A ^ B ^ B = A
A ^ A = 0

Step-by-step:

a = 5, b = 7
a = a ^ b → 2
b = a ^ b → 5
a = a ^ b → 7

Final values:

a = 7
b = 5

Although this method is clever, modern compilers usually optimize normal swapping efficiently. However, XOR swapping is still a popular interview question and demonstrates understanding of bitwise operations.

Question 93: Mutex Concept (Resource Protection)

#include <stdio.h>
int mutex = 1;
void useUART() {
    if(mutex == 1) {
        mutex = 0;
        printf("UART Access\n");
        mutex = 1;
    }
    else {
        printf("UART Busy\n");
    }
}

int main() {
    useUART();
    useUART();
    return 0;
}

Output

UART Access
UART Access

Explanation

This program demonstrates the concept of a mutex (Mutual Exclusion) used in RTOS systems.

A mutex ensures that only one task can access a shared resource at a time.

In embedded systems, shared resources include:

  • UART communication
  • SPI or I2C buses
  • Shared memory buffers
  • Hardware peripherals

Execution flow:

mutex = 1 → resource available

First call:

mutex becomes 0
Resource accessed
mutex restored to 1

Second call also accesses the resource.

In real RTOS systems like FreeRTOS, mutexes prevent race conditions when multiple tasks attempt to use the same hardware resource.


Question 94: Detect Power of Two

#include <stdio.h>
int main() {
    int num = 16;
    if((num & (num - 1)) == 0)
        printf("Power of Two");
    else
        printf("Not Power of Two");
    return 0;
}

Output

Power of Two

Explanation

This program checks whether a number is a power of two using bitwise operations.

Binary of 16:

10000

When we compute:

num - 1 = 15
01111

Performing AND:

10000
01111
-----
00000

Result becomes 0, confirming the number is a power of two.

This trick is commonly used in embedded systems for:

  • Buffer size validation
  • Memory alignment checks
  • DMA configuration
  • Power-of-two ring buffers

It is very efficient because it uses only one bitwise operation.


Question 95: ISR Flag Handling

#include <stdio.h>
volatile int flag = 0;
void ISR() {
    flag = 1;
}

int main() {
    ISR();
    if(flag)
        printf("Interrupt Handled");
    return 0;
}

Output

Interrupt Handled

Explanation

This program simulates an Interrupt Service Routine (ISR) setting a flag.

In embedded systems:

  1. Hardware interrupt occurs
  2. ISR executes
  3. ISR sets a flag
  4. Main loop detects the flag and processes it

Example flow:

ISR → flag = 1
Main loop checks flag
Main loop executes task

The variable is declared volatile because its value may change outside the normal program flow, such as:

  • hardware interrupts
  • DMA updates
  • RTOS context switching

Without volatile, the compiler may optimize the variable and ignore external changes, leading to incorrect behavior.


Question 96: Find Second Largest Element

#include <stdio.h>
int main() {
    int arr[] = {12,45,67,23,89};
    int largest = arr[0];
    int second = arr[0];
    for(int i=1;i<5;i++) {
        if(arr[i] > largest) {
            second = largest;
            largest = arr[i];
        }
        else if(arr[i] > second && arr[i] != largest)
            second = arr[i];
    }
    printf("%d", second);
    return 0;
}

Output

67

Explanation

This program finds the second largest element in an array.

Steps:

Initial values:

largest = 12
second = 12

Iteration:

45 → largest = 45, second = 12
67 → largest = 67, second = 45
23 → ignored
89 → largest = 89, second = 67

Final result:

second largest = 67

This logic is useful in embedded applications such as:

  • peak detection in signals
  • priority ranking
  • sensor data filtering

Question 97: Memory Alignment Check

#include <stdio.h>
int main() {
    int address = 32;
    if(address % 4 == 0)
        printf("Aligned");
    else
        printf("Not Aligned");
    return 0;
}

Output

Aligned

Explanation

Memory alignment is very important in embedded systems.

Most processors prefer data to be stored at aligned memory addresses.

Example:

4-byte integer → address divisible by 4
8-byte double → address divisible by 8

Given:

address = 32

Checking alignment:

32 % 4 = 0

So the address is properly aligned.

Aligned memory access is faster and avoids bus faults on some microcontrollers.


Question 98: Reverse a Linked List (DSA)

#include <stdio.h>
#include <stdlib.h>struct Node {
    int data;
    struct Node* next;
};

int main() {
    struct Node *a = malloc(sizeof(struct Node));
    struct Node *b = malloc(sizeof(struct Node));
    struct Node *c = malloc(sizeof(struct Node));
    a->data=1; a->next=b;
    b->data=2; b->next=c;
    c->data=3; c->next=NULL;
    struct Node *prev=NULL,*curr=a,*next=NULL;

    while(curr!=NULL){
        next=curr->next;
        curr->next=prev;
        prev=curr;
        curr=next;
    }
    while(prev!=NULL){
        printf("%d ",prev->data);
        prev=prev->next;
    }
    return 0;
}

Output

3 2 1

Explanation

This program reverses a singly linked list, which is an important data structure used in embedded firmware.

Initial list:

1 → 2 → 3

During reversal:

prev ← curr ← next

Links are reversed step-by-step:

1 ← 2 ← 3

Final output:

3 → 2 → 1

Linked list reversal is useful for:

  • packet processing
  • buffer manipulation
  • data structure management

Question 99: Task Delay Counter

#include <stdio.h>
int main() {
    int tick = 0;
    while(tick < 5) {
        printf("Task running\n");
        tick++;
    }
    return 0;
}

Output

Task running
Task running
Task running
Task running
Task running

Explanation

This program simulates a simple task delay mechanism.

In RTOS systems, tasks often run based on system ticks generated by a hardware timer.

Example:

Tick interrupt → scheduler runs
Task executes
Task delays for N ticks

In FreeRTOS, this is typically done using:

vTaskDelay()

This mechanism allows tasks to sleep for a specific amount of time while other tasks run.


Question 100: Bit Masking (Hardware Register Control)

#include <stdio.h>
int main() {
    int reg = 0b10101010;
    int mask = 0b00001111;
    printf("%d", reg & mask);
    return 0;
}

Output

10

Explanation

Bit masking is widely used in embedded systems to read specific bits from hardware registers.

Given:

reg  = 10101010
mask = 00001111

Applying AND operation:

10101010
00001111
--------
00001010

Binary 00001010 equals 10 in decimal.

Masking allows firmware to:

  • read status bits
  • enable or disable hardware features
  • isolate specific register fields

Almost every embedded driver uses bit masking operations.

This was about “Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations”. Thank you for reading.

Also, read:

Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations. Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations. Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations. Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations. Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations. Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations. Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations. Top 100 C Coding-based “Predict The Output” Interview Questions With Explanations