CLOSE

🔙 A bit of flashback – What Is a Pointer?

A pointer is a variable that stores the address of another variable.

int a = 5;
int *p = &a; // p is a pointer to int
  • *pdereferences the pointer (gives the value at address)
  • &a gives the address of a

Operator Precedence in Pointer Declarations

Understanding how pointer declarations work in C/C++ relies heavily on operator precedence – just like arithmetic expressions.

Here's a simple rule of thumb:

The arrangement of operators in a declarations determines the type.

Pointer Operators and Their Precedence

OperatorDescriptionPrecedenceAssociativityInterpretation
()Function callHighestLeft-to-rightFunction taking args and returning type
[]Array subscriptHighestLeft-to-rightArray of type
*IndirectionLowerRight-to-leftPointer to type

📐 How to Read Based on Precedence

  • Parentheses () and arrays [] bind the strongest, and are evaluated left to right.
  • The indirection operator * binds more weakly, and is evaluated right to left.
  • Use parentheses to group expressions properly and override default binding.

🔄 Basic Combinations Table

DeclarationStructureMeaning
*()*foo()A function returning a pointer
(*)()(*foo)()A pointer to a function
*[]*foo[]An array of pointers
(*)[](*foo)[]A pointer to an array
[][]foo[][]A two-dimensional array
****fooA pointer to a pointer

Anatomy of a Pointer Declaration

Let's look at the simple case:

int *p;

To read this correctly, use the Right-Left Rule:

  • p is a pointer to int

This rule is critical as you progress. Always start from the variable name and go outward.

The Right-Left Rule for Reading Declarations

Right-Left Rule: Start with the variable name (identifier), then go right (if possible), then left, repeating this process outward.

Let's break down a few examples:

int *p;
  • Start at p
  • Go right: nothing
  • Go left: * -> “pointer to”
  • Go left: int -> “pointer to int”

p is a pointer to an int.

Common Pointer Declaration Patterns

Let's dive into frequently encountered pointer declarations.

Pointer to Pointer

int **p;
  • pp is a pointer to a pointer to an int.
  • Read as: “pp -> pointer to (*) pointer to (*) int”.

Pointer to Array

int (*ptr)[10];
  • ptr is a pointer to an array of 10 ints.

Parentheses are essential. without them:

int *ptr[10];  // ptr is an array of 10 pointers to int!

Function Returning Pointer

int *func();
  • func is a function that returns a pointer to an int.
  • Function has () -> returns → pointer * to -> int.

Pointer to a Function

int (*funcPtr)();
  • funcPtr is a pointer to a function returning int.

Array of Pointers

int *arr[5];
  • arr is an array of 5 pointers to int.

Advances Examples

Function Returning Pointer to Array

int (*func())[10];
  • func() -> function
  • Returns (*…)[10] -> pointer to an array of 10 int.

func is a function that returns a pointer to an array of 10 int.

Array of Pointers to Functions

int (*arr[3])();
  • arr[3] is an array of 3 elements
  • Each is (*…)() -> pointer to function returning int

arr is an array of 3 pointers to functions returning int.

Pointer to Function Returning Pointer

int *(*ptr)();
  • ptr is a pointer to a function that returns a pointer to int.

Function Pointer as Argument

void registerCallback(void (*callback)(int));
  • registerCalllback takes a pointer to a function that takes an int and returns void.

🔧 Tools for Help

🔍 Online Decoder

  • cdecl.org — Converts English to C declarations and vice versa