Array Pointers Interview Quiz- Free C Programming Course

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

Free C Programming Course · Chapter 8 · Pointers

Array Pointers Interview Quiz

Sort out array of pointers vs pointer to array in C, then test yourself with a 10-question quiz, a coding challenge and 10 interview questions. Final lecture of this block of our free C tutorial for embedded C programming.

10
Quiz questions with answers
10
Interview questions
1
Coding challenge with solution

What You Will Learn

Two declarations differ by a pair of parentheses and mean completely different things. The question array of pointers vs pointer to array in C is a favourite in written tests and embedded interviews, because it checks whether you really understand declarator precedence. In this closing lecture of our free C programming course block, we compare them side by side, run a program to measure their sizes and strides, and then you test yourself.

  • How to tell int *ap[3] from int (*pa)[3] at a glance.
  • How the two differ in size and in what pointer arithmetic does to them.
  • A one-page recap of passing arrays to functions in all dimensions.
  • A quiz, a coding challenge and interview questions, each with answers you can open after you try.

Prerequisites

Complete the earlier lectures of this chapter: passing 1-D arrays, array parameters as pointers, passing 2-D arrays and the array of pointers. Have GCC or Clang ready to run the demo.

Array of Pointers vs Pointer to Array in C

Both declarations contain an asterisk and a bracket pair. What separates them is which one binds to the name first. Brackets have higher precedence than the asterisk, so without parentheses the name is an array. With parentheses around the starred name, the name is a pointer.

DeclarationRead asWhat it stores
int *ap[3]ap is an array of 3 pointers to intThree separate addresses
int (*pa)[3]pa is a pointer to an array of 3 intsOne address of a whole 3-int array

Two Very Different Shapes

ap : three pointersap[0] → xap[1] → yap[2] → z
pa : one pointerpa → [ 7, 8, 9 ] as one block
ap + 1 steps over one pointer. pa + 1 steps over a whole 3-int array.

Why Pointer Arithmetic Differs

Adding 1 to a pointer moves it by the size of the thing it points to. For ap, which decays to a pointer to int *, one step is one pointer wide. For pa, one step is the size of a full int[3]. You met the same effect for row pointers in the 2-D array lecture, where g + 1 jumped a whole row. A pointer to array is exactly what a 2-D array parameter becomes.

Build and Run the Comparison

Save this short program as ep_ptr_vs_array_ptr.c.

#include <stdio.h>
#include <stddef.h>

int main(void)
{
    int row[3] = {7, 8, 9};
    int x = 1, y = 2, z = 3;

    int *ap[3]   = { &x, &y, &z };   /* array of 3 pointers to int   */
    int (*pa)[3] = &row;             /* pointer to an array of 3 ints */

    printf("sizeof(ap)  = %zu   sizeof(pa)  = %zu   sizeof(*pa) = %zu\n",
           sizeof(ap), sizeof(pa), sizeof(*pa));

    printf("*ap[1]    = %d\n", *ap[1]);
    printf("(*pa)[1]  = %d\n", (*pa)[1]);

    printf("ap + 1 moves %td bytes\n", (char *)(ap + 1) - (char *)ap);
    printf("pa + 1 moves %td bytes\n", (char *)(pa + 1) - (char *)pa);
    return 0;
}
gcc -std=c11 -Wall -Wextra -o ep_ptr_vs_array_ptr ep_ptr_vs_array_ptr.c
./ep_ptr_vs_array_ptr

Expected output on a 64-bit Linux machine:

sizeof(ap)  = 24   sizeof(pa)  = 8   sizeof(*pa) = 12
*ap[1]    = 2
(*pa)[1]  = 8
ap + 1 moves 8 bytes
pa + 1 moves 12 bytes

What the Output Proves

  • sizeof(ap) is 24: three pointers of 8 bytes each. sizeof(pa) is 8: a single pointer.
  • sizeof(*pa) is 12: the pointed-to object is an array of three 4-byte integers.
  • Element access differs: *ap[1] follows a stored pointer to y, while (*pa)[1] first dereferences to the array, then indexes it. The parentheses are essential, since *pa[1] would mean something else entirely.
  • The step sizes, 8 and 12 bytes, are exactly the sizes of the objects each pointer targets.
Interview tip: if someone writes a declaration without parentheses and calls it a “pointer to an array”, it is wrong. Always check the parentheses, then read from the name outward.

Quick Recap of the Whole Block

You passParameter type that resultsLength available?
int a[6] (1-D array)int *No; pass a count
int g[3][5] (2-D array)int (*)[5]Row width yes, row count no
int *t[3] (array of pointers)int **No; pass a count

In every case only a base address crosses the call, so the callee works on the caller’s original data, and any size that is not part of the pointed-to type must travel as a separate argument.

Common Mistakes and Troubleshooting

  • Writing int *p[3] when you wanted a pointer to a 3-int array. The missing parentheses give you an array of pointers.
  • Treating a 2-D array as int **. The types are incompatible; use a pointer to a row.
  • Using sizeof on a parameter to find an element count.
  • Forgetting that *pa[1] and (*pa)[1] are different expressions.

Best Practices, Performance and Security

  • Write the pair (pointer, length) in every buffer function signature.
  • Use const for read-only inputs and for tables you want in flash.
  • Validate indexes and lengths that come from outside the program before using them.
  • Use a typedef for complex declarators, such as a row type, when readability suffers.

Quiz: Test Your Understanding

Try each question before opening the answer. Assume a 64-bit Linux machine with 4-byte int unless a question says otherwise.

  1. For void f(int a[10]);, what is sizeof(a) inside the function?

    • A) 40
    • B) 8
    • C) 10
    • D) 4
    Show answer

    B) 8. The parameter is an int *, so you get the pointer size. On a 32-bit microcontroller it would be 4.

  2. Which prototypes are equivalent?

    • A) void f(int a[]);
    • B) void f(int a[5]);
    • C) void f(int *a);
    • D) All of the above
    Show answer

    D) All of the above. Each declares a pointer to int parameter.

  3. What is int (*p)[4];?

    • A) An array of 4 pointers to int
    • B) A pointer to an array of 4 ints
    • C) A pointer to 4 ints separately
    • D) A syntax error
    Show answer

    B) A pointer to an array of 4 ints. The parentheses bind the star to p.

  4. What is sizeof(int *q[4]) for a real array on a 64-bit system?

    • A) 8
    • B) 16
    • C) 32
    • D) 4
    Show answer

    C) 32. It is four pointers of 8 bytes each.

  5. With int g[3][5]; int (*p)[5] = g;, how many bytes does p + 1 advance?

    • A) 4
    • B) 5
    • C) 20
    • D) 60
    Show answer

    C) 20. One step skips a full row of five 4-byte integers.

  6. Can a function modify the elements of an array passed by the caller?

    • A) No, they are copied
    • B) Yes, it works on the original
    • C) Only if the array is global
    • D) Only with the register keyword
    Show answer

    B) Yes. The function receives the base address, so it works on the original array.

  7. What does this print?

    static void bump(int *p) { p[2] += 10; p = NULL; }
    int v[4] = {1, 2, 3, 4};
    bump(v);
    printf("%d %d\n", v[2], v[0]);
    • A) 3 1
    • B) 13 1
    • C) 13 NULL
    • D) A crash
    Show answer

    B) 13 1. The element change is shared with the caller. Setting the local pointer to NULL affects only the callee’s copy of the pointer.

  8. Is void f(int a[][]); valid?

    • A) Yes
    • B) No, inner dimensions must be given
    • C) Yes, but only in C99
    • D) Only if the first dimension is 1
    Show answer

    B) No. Only the leftmost dimension may be omitted, because the others determine the row size.

  9. Inside a function with parameter int *buf, what does sizeof(buf) / sizeof(buf[0]) give on a 64-bit system?

    • A) The element count
    • B) 2
    • C) 8
    • D) 4
    Show answer

    B) 2. It is 8 divided by 4. The result has nothing to do with the real buffer length.

  10. Given int *probe[3] = { &a, &b, &c };, what does *probe[1] = 0; do?

    • A) Sets probe[1] to 0
    • B) Sets b to 0
    • C) Sets all three to 0
    • D) Does not compile
    Show answer

    B) It sets b to 0. The subscript picks the pointer, and the star writes to its target.

Coding Challenge: Row Sums

Write a function that receives a matrix with a run-time width and fills an output array with the sum of each row. Try it yourself first, using what you learned about 2-D parameters. The function should take the row count, the column count, a read-only matrix and an output array.

Show a solution
#include <stdio.h>
#include <stddef.h>

static void row_sums(size_t rows, size_t cols, const int m[rows][cols], int out[rows])
{
    for (size_t r = 0; r < rows; r++) {
        int total = 0;
        for (size_t c = 0; c < cols; c++) {
            total += m[r][c];
        }
        out[r] = total;
    }
}

int main(void)
{
    int m[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int sums[2];
    row_sums(2, 3, m, sums);
    printf("row sums: %d %d\n", sums[0], sums[1]);
    return 0;
}
gcc -std=c11 -Wall -Wextra -o row_sums row_sums.c
./row_sums
row sums: 6 15

The sizes come first so the later parameters can use them. The matrix is const because it is only read, and the output array is an ordinary pointer to the caller’s storage.

Interview Questions on Arrays and Pointers

1. How are arrays passed to functions in C?

By the address of the first element. The parameter is a pointer, so no copy is made and the function can modify the caller’s elements.

2. Why does sizeof on an array parameter give the pointer size?

Because the parameter type is a pointer after adjustment. The array type, and with it the size, is lost at the function boundary.

3. How do you let a function know the number of elements?

Pass a length argument next to the pointer, normally of type size_t, computed in the caller where the real array type is visible.

4. What is the difference between int *p[3] and int (*p)[3]?

The first is an array of three pointers to int. The second is a single pointer to an array of three ints. The parentheses change what binds to the name.

5. What type does a 2-D array parameter become?

A pointer to an array of the inner dimension, for example int (*g)[5] for a matrix with five columns.

6. Why must the column count be given for a 2-D parameter?

Row addresses are computed using the row size, which equals the column count times the element size. Without it the compiler cannot step from one row to the next.

7. Can you pass a 2-D array where int ** is expected?

No. A true 2-D array is one contiguous block, while int ** expects an array of row pointers. The types are incompatible.

8. How do you keep a table of strings in flash on a microcontroller?

Declare it static const char *const names[] so both the characters and the pointers are read-only, which lets the linker place the table in flash.

9. What happens if a function reassigns its array parameter?

Only the function’s local pointer changes. The caller’s array and name are unaffected.

10. What are common security problems with array parameters?

Unchecked lengths and indexes lead to buffer overruns. Validate every externally supplied length against the real capacity before reading or writing.

Key Takeaways

  • Array of pointers: int *ap[3]. Pointer to array: int (*pa)[3].
  • Pointer arithmetic steps by the size of the pointed-to object: one pointer for the first, one whole array for the second.
  • Every array argument becomes a pointer; carry lengths separately.
  • Only the leftmost dimension of a multi-dimensional parameter can be left out.

Conclusion

You have now covered how arrays travel into functions in one and two dimensions, why sizeof betrays you on array parameters, how an array of pointers organises scattered data, and how to tell it apart from a pointer to an array. These ideas are the daily bread of embedded C programming, and they are exactly what interviewers probe. Revisit the quiz after a day or two; repeating questions you got wrong is the quickest way to make the rules automatic. Keep going with the free C programming course, and continue to the next chapter block when you are ready.

Suggested Images for This Lecture

  • Comparison diagram of an array of pointers and a pointer to an array. Alt text: “array of pointers vs pointer to array in C comparison diagram”.
  • Terminal screenshot of the size and stride output. Alt text: “free C programming course array of pointers vs pointer to array in C program output”.
  • Quiz summary graphic. Alt text: “embedded C programming interview quiz on arrays and pointers free embedded C course”.

Frequently Asked Questions

How do I remember the difference between the two declarations?

Look for parentheses around the starred name. If they are there, the name is a pointer; if not, the brackets bind first and the name is an array.

Which one does a 2-D array parameter turn into?

A pointer to an array, such as int (*g)[5], not an array of pointers.

When would I use a pointer to an array in real code?

Mainly when handling fixed-width records or matrix rows, for example to give a function one row at a time or to walk a table of fixed-size entries.

Are these topics asked in embedded interviews?

Very often. Declaration reading, sizeof on parameters and array decay are classic screening questions for embedded roles.

Should I memorise pointer sizes?

No. Remember that they depend on the target, commonly 4 bytes on 32-bit microcontrollers and 8 bytes on 64-bit systems, and use sizeof in code.

Where can I learn more for free?

EmbeddedPathashala offers a free C programming course, a free embedded C course and free Linux kernel and device driver courses.

Keep Learning With the Free Embedded C Course

Review the quiz, try the challenge on your own board or PC, and move on to the next chapter of our free C programming course.

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *