Menu
CoddyTech

C Arrays and Strings Interview Questions

Arrays, how they decay to pointers, null-terminated strings and the functions that overflow buffers.

10 questions
  1. What does sizeof return for an array versus a pointer to it?

    C
    #include <stdio.h>
    
    int main(void) {
        int arr[10] = {0};
        int *p = arr;
        printf("%zu %zu\n", sizeof arr, sizeof p);
        return 0;
    }

    It prints 40 8: the whole array is 10 four-byte ints and the pointer is 8 bytes on a 64-bit build (both implementation-defined). An array decays to a pointer in most expressions but is not one. So inside a function, a parameter int a[] is an int * and sizeof a / sizeof a[0] does not give the length. See pointers and arrays.

  2. What do sizeof and strlen return for char s[] = "hello"?

    C
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        char s[] = "hello";
        printf("%zu %zu\n", sizeof s, strlen(s));
        return 0;
    }

    It prints 6 5. The array holds 5 characters plus the terminating '\0', which strlen does not count. A copy needs strlen(s) + 1 bytes. See strings in C.

  3. What is the difference between char s[] = "hi" and char *s = "hi"?

    char s[] = "hi" is a 3-byte array holding a copy of the literal, which you may modify. char *s = "hi" points to the literal, usually in read-only memory, and writing through it is undefined behavior.

    char a[] = "hi";
    a[0] = 'H';          /* fine: a is your array */
    
    char *p = "hi";
    p[0] = 'H';          /* undefined behavior: writes to a string literal */
    
    const char *q = "hi"; /* the honest declaration: the compiler now rejects q[0] = 'H' */
    

    In C++ the literal is const char[3], so char *p = "hi" is ill-formed there since C++11.

  4. Write a C function that reverses a string in place.

    Swap the characters at both ends and move toward the middle: O(n) time, O(1) space.

    C
    #include <stdio.h>
    #include <string.h>
    
    void reverse(char *s) {
        size_t len = strlen(s);
        if (len < 2) return;
        for (size_t i = 0, j = len - 1; i < j; i++, j--) {
            char t = s[i];
            s[i] = s[j];
            s[j] = t;
        }
    }
    
    int main(void) {
        char word[] = "interview";
        reverse(word);
        printf("%s\n", word);
        return 0;
    }

    It prints weivretni. The len < 2 check matters: size_t is unsigned, so len - 1 on an empty string wraps. Passing a literal, as in reverse("abc"), writes to read-only memory.

    Practice it: Reverse a String, Palindrome String, Valid Palindrome

  5. Why is strcpy unsafe, and is strncpy the fix?

    strcpy does not know the destination's size, so a long source overflows it. strncpy is no fix: when the source is too long it leaves the result without a null terminator. Use snprintf, which terminates and returns the length it wanted.

    C
    #include <stdio.h>
    
    int main(void) {
        char buf[8];
        int needed = snprintf(buf, sizeof buf, "%s", "hello world");
        printf("buf = \"%s\", needed = %d\n", buf, needed);
        if (needed >= (int) sizeof buf) printf("truncated\n");
        return 0;
    }

    It keeps hello w, reports 11 and prints truncated. Never use gets, removed in C11. See string functions.

  6. Can you compare two C strings with ==?

    C
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        char a[] = "abc";
        char b[] = "abc";
        printf("%d %d\n", a == b, strcmp(a, b) == 0);
        return 0;
    }

    It prints 0 1. a == b compares the addresses of two separate arrays; strcmp compares characters and returns 0 when they match. Its nonzero results are any negative or positive value, so test the sign, never == 1.

  7. Is 2[a] valid C, and what does it evaluate to?

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

    It prints 30. The standard defines a[i] as *(a + i), and addition commutes, so 2[a] is a[2]. It also explains why p[-1] is valid when p points into the middle of an array.

  8. How do you pass a 2D array to a function in C?

    The function must know every dimension except the first, to compute m[i][j]. Fix the column count in the type, or (C99) pass the dimensions first as a variable length array parameter.

    C
    #include <stdio.h>
    
    void print_fixed(int m[][3], int rows) {
        for (int i = 0; i < rows; i++)
            printf("%d %d %d\n", m[i][0], m[i][1], m[i][2]);
    }
    
    int sum_vla(int rows, int cols, int m[rows][cols]) {
        int s = 0;
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++) s += m[i][j];
        return s;
    }
    
    int main(void) {
        int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
        print_fixed(grid, 2);
        printf("sum = %d\n", sum_vla(2, 3, grid));
        return 0;
    }

    int ** does not work: a 2D array is one block, not an array of row pointers. VLAs became optional in C11, C23 again requires VLA parameter types like this one, and MSVC lacks them; see arrays on cppreference.

    Practice it: Transpose Matrix, Richest Customer Wealth

  9. How do you convert a string to an integer in C, and why is strtol better than atoi?

    Use strtol. atoi returns 0 both for "0" and for garbage, and an out-of-range value is undefined behavior, so it cannot report an error. strtol gives you an end pointer and sets errno to ERANGE on overflow.

    C
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int parse_int(const char *s, long *out) {
        char *end;
        errno = 0;
        long v = strtol(s, &end, 10);
        if (end == s || *end != '\0' || errno == ERANGE) return 0;
        *out = v;
        return 1;
    }
    
    int main(void) {
        const char *inputs[] = {"42", "-7", "12abc", "abc"};
        for (int i = 0; i < 4; i++) {
            long v;
            if (parse_int(inputs[i], &v)) printf("%s -> %ld\n", inputs[i], v);
            else printf("%s -> invalid\n", inputs[i]);
        }
        printf("atoi(\"abc\") = %d\n", atoi("abc"));
        return 0;
    }

    It accepts 42 and -7 and rejects 12abc and abc, while atoi("abc") quietly returns 0. Check end == s (no digits at all) and *end != '\0' (trailing junk). See string conversion.

  10. Write a C program to find the second largest element in an array.

    Track the largest and the second largest in one pass: O(n) time, O(1) space. A new maximum pushes the old one down; a value strictly between the two replaces the second.

    C
    #include <stdio.h>
    
    /* Returns 1 and stores the answer in *out, or 0 if there is none. */
    int second_largest(const int *a, int n, int *out) {
        if (n < 2) return 0;
        int first = a[0], second = 0, has_second = 0;
        for (int i = 1; i < n; i++) {
            if (a[i] > first) {
                second = first;
                has_second = 1;
                first = a[i];
            } else if (a[i] < first && (!has_second || a[i] > second)) {
                second = a[i];
                has_second = 1;
            }
        }
        if (has_second) *out = second;
        return has_second;
    }
    
    int main(void) {
        int a[] = {12, 35, 1, 10, 35, 34};
        int same[] = {7, 7, 7};
        int s;
        if (second_largest(a, 6, &s)) printf("%d\n", s);
        if (!second_largest(same, 3, &s)) printf("no second largest\n");
        return 0;
    }

    It prints 34 and no second largest. The traps are a repeated maximum (35 appears twice and the answer is still 34) and an array with no second distinct value. The flag avoids an INT_MIN sentinel, which fails when INT_MIN is in the data.

    Practice it: Second Largest Number, Find the Largest Number

Coddy programming languages illustration

Learn to code with Coddy

Get started