Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Output Questions - Part 2
C

Output Questions - Part 2

Test your C knowledge with 15 more predict-the-output questions covering precedence, unsigned arithmetic, recursion, and memory.

16. What does this precedence program print?

#include <stdio.h>

int main(void) {
    int a = 1, b = 2, c = 3;

    printf("%d\n", a + b * c);
    printf("%d\n", (a + b) * c);
    printf("%d\n", 2 * a + b++);
    printf("%d\n", b);
    return 0;
}

Output:

7
9
4
3

* binds tighter than +, so a + b * c is 1 + 6 = 7, while (a + b) * c is 3 * 3 = 9. In 2 * a + b++, the ++ applies only to b; 2 * 1 + 2 = 4, and b becomes 3. Postfix ++ binds tightest of all.

17. What does this unsigned-wraparound program print?

#include <stdio.h>

int main(void) {
    unsigned int u = 4294967295u;

    printf("%u\n", u);
    printf("%u\n", u + 1);
    return 0;
}

Output:

4294967295
0

Unsigned arithmetic wraps around modulo 2^32 (defined behavior, unlike signed overflow which is UB). 4294967295 is the largest 32-bit unsigned value; adding 1 wraps to 0. This wrap-around is guaranteed by the standard for unsigned types.

18. What does this signed/unsigned comparison print?

#include <stdio.h>

int main(void) {
    int x = -1;
    unsigned int y = 1;

    if (x < y)
        printf("less\n");
    else
        printf("not less\n");
    return 0;
}

Output:

not less

When int and unsigned int are compared, the int is converted to unsigned int. -1 becomes the huge value 4294967295, which is not less than 1 — so the else branch prints "not less". Mixing signed and unsigned comparisons is one of the most dangerous C bugs; this is a famous interview question.

19. What does this logical-operator program print?

#include <stdio.h>

int main(void) {
    int a = 5, b = 0;

    printf("%d\n", a && b);
    printf("%d\n", a || b);
    printf("%d\n", !a);
    printf("%d\n", !!a);
    return 0;
}

Output:

0
1
0
1

Logical operators produce int 0 or 1, not arbitrary truthiness values. 5 && 0 is 0, 5 || 0 is 1, !5 is 0, and !!5 normalizes any truthy value to exactly 1.

20. What does this ternary operator print?

#include <stdio.h>

int main(void) {
    int x = 10;

    printf("%d\n", x > 5 ? x : x * 2);
    printf("%d\n", x > 5 ? x++ : x--);
    printf("%d\n", x);
    return 0;
}

Output:

10
10
11

The ternary cond ? a : b evaluates only the chosen branch. x > 5 is true, so the first prints 10. In the second, the true branch x++ is evaluated: it yields the old value 10 and increments x to 11. The final print shows 11. The unselected branch is never evaluated.

21. What does this recursion program print?

#include <stdio.h>

int fib(int n) {
    if (n <= 1)
        return n;
    return fib(n - 1) + fib(n - 2);
}

int main(void) {
    printf("%d\n", fib(7));
    return 0;
}

Output:

13

fib(0)=0, fib(1)=1, and each further term is the sum of the previous two. The sequence goes 0, 1, 1, 2, 3, 5, 8, 13 — so fib(7) is 13. This classic recursive trace tests your ability to unroll a call tree.

22. What does this array-init program print?

#include <stdio.h>

int main(void) {
    int a[5] = {1, 2, 3};
    int i;

    for (i = 0; i < 5; i++)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}

Output:

1 2 3 0 0 

In an initializer, missing elements are filled with zero. int a[5] = {1, 2, 3} gives {1, 2, 3, 0, 0}. The loop prints all five, trailing zeros included. This is a frequent campus question about partial array initialization.

23. What does this 2D-array print?

#include <stdio.h>

int main(void) {
    int m[2][2] = {{1, 2}, {3, 4}};
    int *p = &m[0][0];

    printf("%d\n", *(p + 2));
    printf("%d\n", m[1][0]);
    printf("%d\n", *(p + 1 + 1));
    return 0;
}

Output:

3
3
3

A 2D array is stored row-major — row 0 (1, 2) then row 1 (3, 4). p points to element 0. *(p + 2) is the 3rd element, 3; m[1][0] is 3; and *(p + 1 + 1) is the 3rd element again, 3.

24. What does this string-copy program print?

#include <stdio.h>
#include <string.h>

int main(void) {
    char src[] = "world";
    char dst[10];

    strcpy(dst, src);
    printf("%s\n", dst);
    printf("%zu\n", strlen(dst));
    printf("%zu\n", sizeof(dst));
    return 0;
}

Output:

world
5
10

strcpy copies the string including its '\0' terminator. strlen counts characters before the null terminator (5), while sizeof returns the declared array size (10). This strlen vs sizeof distinction on strings is a classic C interview gotcha.

25. What does this pointer-to-array program print?

#include <stdio.h>

int main(void) {
    int arr[3] = {10, 20, 30};
    int *p = arr;
    int (*pa)[3] = &arr;

    printf("%d\n", p[1]);
    printf("%d\n", (*pa)[2]);
    printf("%d\n", (int)((pa + 1) - &arr));
    return 0;
}

Output:

20
30
1

p is a plain int*, so p[1] is 20. pa is a pointer to the whole 3-element array; (*pa)[2] dereferences to the array and indexes element 2 → 30. (pa + 1) - &arr is pointer subtraction between two pointers to the same array type, which counts elements of the pointed-to type — and pa + 1 is one whole array (3 ints) ahead, so the difference is 1. This is why &arr (pointer to array) differs from arr (pointer to element): arr + 1 would skip only one int.

26. What does this function-call by value print?

#include <stdio.h>

void modify(int x) {
    x = 99;
}

int main(void) {
    int a = 5;
    modify(a);
    printf("%d\n", a);
    return 0;
}

Output:

5

C passes arguments by value: modify receives a copy of a, so assigning x = 99 inside the function does not affect a in main. To change the caller’s variable, you must pass a pointer (&a) and dereference it. This is the fundamental “C is pass-by-value” question.

27. What does this pointer-passing program print?

#include <stdio.h>

void modify(int *x) {
    *x = 99;
}

int main(void) {
    int a = 5;
    modify(&a);
    printf("%d\n", a);
    return 0;
}

Output:

99

Passing &a gives the function the address of a. Dereferencing *x = 99 writes through that pointer, mutating a in main. This is how C simulates pass-by-reference — the pointer is still passed by value, but it lets you reach the caller’s object.

28. What does this string-literal print?

#include <stdio.h>

int main(void) {
    char *p = "hello";
    char s[] = "hello";

    printf("%c\n", p[1]);
    printf("%c\n", s[1]);
    printf("%zu\n", (size_t)(sizeof(p) > sizeof(s) ? 1 : 0));
    return 0;
}

Output:

e
e
1

p[1] and s[1] both index the second character, 'e'. But p is a pointer (8 bytes on 64-bit) while s is a 6-element array (6 bytes). So sizeof(p) > sizeof(s) is 8 > 6, printing 1. Strings as pointer vs array: same indexing, different sizeof.

29. What does this nested-loop program print?

#include <stdio.h>

int main(void) {
    int i, j;

    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            if (j == 1)
                break;
            printf("%d%d ", i, j);
        }
    }
    printf("\n");
    return 0;
}

Output:

00 10 20 

The inner loop breaks when j == 1, so only j = 0 prints each time — 00, then 10, then 20. Crucially, break only exits the innermost loop; the outer loop continues, giving three iterations of the outer loop.

30. What does this dynamic-memory program print?

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *arr = malloc(3 * sizeof(int));
    arr[0] = 7;
    arr[1] = 8;
    arr[2] = 9;

    printf("%d\n", arr[1]);
    printf("%d\n", *arr + 1);
    free(arr);
    return 0;
}

Output:

8
8

arr[1] is 8. *arr + 1 dereferences arr first (7) then adds 18 — precedence makes *arr + 1 parse as (*arr) + 1, not *(arr + 1). The pointer-to-array indexing and the dereference-then-add distinction are both being tested. The free releases the heap memory.

My Private Notes

Notes are auto-saved locally to this device.