ProgrammingC Developer

Explain the detailed features of working with pointers to arrays and arrays of pointers in the C language. How to properly declare, use, and distinguish them from each other?

Pass interviews with Hintsage AI assistant

Answer.

Historically, pointers became the foundation of memory work in the C language and provided a flexible mechanism for efficient access to array elements and dynamic structures. However, the syntax and semantics of pointers to arrays and arrays of pointers often cause confusion.

Problem: Beginners often confuse pointer to array and array of pointers, leading to improper memory usage, parameter passing errors, and difficult-to-construct syntax errors.

Solution:

  • Pointer to array: is a variable that holds the address of the entire array (one block of memory).
  • Array of pointers: is an array where each element is a pointer (e.g., an array of strings).

Example declaration and usage:

// Pointer to an array of 10 int: int (*p)[10]; int arr[10]; p = &arr; // Array of 10 pointers to int int *ap[10]; for (int i = 0; i < 10; ++i) { ap[i] = &arr[i]; } // How to get an element using a pointer to an array: (*p)[2] = 5; // the third element of arr // How to get a value using an array of pointers: *ap[2] = 8; // the third element of arr via ap

Key features:

  • The type int (*p)[N] means a pointer to an array of N elements (p has only one memory).
  • The type int *a[N] means an array of N pointers, each pointing somewhere (e.g., to a string).
  • Syntax and parenthesis precedence: int (*p)[N], not int *p[N]!

Tricky questions.

**Are int p[10] and int (p)[10] the same?

No. int *p[10] is an array of 10 pointers to int. int (*p)[10] is a pointer to an array of 10 int. A lot of confusion arises without the parentheses!

Code example:

int arr[10]; int *p[10]; // array of pointers int (*q)[10] = &arr; // pointer to an array

*Can a regular pointer to int be freely assigned to a variable of type int (p)[10]?

No. A regular int * points to a single element, while int (*p)[10] points to an array of 10 integers; the types are incompatible without explicit casting.

How to properly pass a two-dimensional array to a function?

You need to explicitly specify the size of the second dimension:

void foo(int a[][4], int n); // array of n rows with 4 elements

or use a pointer to an array:

void bar(int (*a)[4], int n);

Typical mistakes and anti-patterns

  • Incorrect declarations without parentheses.
  • Confusing types between array of pointers and pointer to array.
  • Errors in passing two-dimensional arrays to functions.

Real-life example

Negative case

An engineer declares a variable as int *p[10], tries to assign it &arr, where arr is int arr[10] and accesses it as an array, resulting in a compilation error or invalid behavior.

Pros:

  • Simplest notation.

Cons:

  • Non-obvious runtime errors, incorrect memory handling.

Positive case

A developer carefully uses parentheses: int (*p)[10], clearly understands the difference, correctly passes arrays to functions, uses typedef for easier declarations.

Pros:

  • Safe and clear code, absence of type errors.

Cons:

  • Excessive syntax, requires attention to detail.