Concepts / Understanding Pointers, Arrays, and References

Understanding Pointers, Arrays, and References

In a declaration, [ ] means array of and * means pointer to.

  • Programming

Two Lines That Look Alike

A declaration is a short line of code that tells the language what a name refers to and what kind of data it holds. Two of the most common declarations in C look almost identical on the page, yet they do very different jobs. One creates a collection of values. The other creates a variable that refers to a single object somewhere else. This article teaches you to read both, so that you can tell them apart before you see any further code.

What do you think happens?

Before reading on, predict what the declaration char v[6]; creates.

  • One char value

  • Six char elements, indexed from v[0] to v[5]

  • A pointer that holds the address of a char

Reveal answer
Answer:

Six char elements, indexed from v[0] to v[5]

The brackets in char v[6]; mean array of, so the name v refers to an array of six char elements. The source states that this declaration creates an array of six char elements, indexed from v[0] to v[5].

Tracing the Array Declaration

Take the declaration char v[6]; and follow what it sets up. The name is v. The type char says what each element holds. The number inside the brackets, 6, says how many elements the array contains. In the declaration, the brackets mean array of, so the whole statement can be read as v is an array of six char. The source also says that the size given in an array declaration must be a constant expression.

Notes on the code
  • char: the type of each element
  • v: the name of the whole collection
  • [6]: the array holds six elements
v[0]first valid indexv[1]validv[2]validv[3]validv[4]validv[5]last valid indexv[6]outside v
Which index labels exist for char v[6], and why does the last valid index come out to 5 rather than 6?

The diagram lists every valid index for v. Read it from left to right: six slots exist, labeled v[0] through v[5]. The label v[6] belongs to no slot in v at all. Writing to or reading from v[6] would fall outside the array.

Why Counting Starts at Zero

Every array in this description starts at index 0, which is its lower bound. The lower bound is the first valid index, and it is not 1. Because of this, the valid indices for an array of size $n$ run from $0$ to $n-1$. The last valid index is always one less than the number of elements. For char v[6], that means $n = 6$, the first index is $0$, and the last valid index is $6-1 = 5$.

Rule

Worked example

Finding the last valid index

An array is declared as char w[10];. What is the last valid index, and is w[10] a valid reference?

  1. 1
    Identify the element count

    The number in the brackets is 10, so the array has $n = 10$ elements.

  2. 2
    Apply the index rule

    Valid indices run from $0$ to $n-1$, which is $0$ to $9$.

  3. 3
    Test the index in question

    The index 10 is greater than 9, so it lies outside the array.

Result

The last valid index is 9, and w[10] is not valid.

Tracing the Pointer Declaration

A pointer is declared in a similar form, but the star symbol does the work that the brackets did for the array. The source reads the star as pointer to. The declaration char *p; therefore creates a pointer variable that is meant to hold the address of an object of type char. The name p does not hold a char itself. It holds the location of a char object somewhere else.

Notes on the code
  • char: the type of object the address should refer to
  • *: pointer to
  • p: the name of the pointer variable
pholds an addresschar objecta single object of typecharrefers to
When p is declared as char *p;, what does p store, and what does it refer to elsewhere?

The diagram shows the relationship. The pointer p stores an address, and that address refers to one object elsewhere. The source says a pointer variable can hold the address of an object of the appropriate type. The type in the declaration tells you what kind of object the address is supposed to point to. A pointer declared as char * is meant for objects of type char, and not for objects of some other type.

Brackets Versus Star

The two declarations use nearly the same pattern, and that is why they are easy to confuse. The difference lies in what each declaration says about the name. The array declaration says the name is a collection of six values. The pointer declaration says the name holds the location of one object of the given type. Reading the symbol is the key step: brackets signal array of, and the star signals pointer to.

charelement typevvariable name[6]array of six elements
Which token gives the element type, which gives the variable name, and which gives the number of elements?
Featurechar v[6];char *p;
Symbol meaning[ ] means array of* means pointer to
What the name refers toA collection of six char elementsThe address of one char object
What is createdSix slots, indexed v[0] to v[5]A variable meant to hold an address
Indexing or dereferencingUse v[0] through v[5]Holds an address of an object of type char

Comparing the array and pointer declarations

Best practice

When you read any declaration, first find the symbol that changes the meaning of the name. If you see brackets, ask how many elements the collection holds. If you see a star, ask what type of object the address should refer to.

Common Mistakes With Arrays and Pointers

  • Common mistake

    Assuming the first index is 1

    What it looks like

    Reading char v[6]; and expecting v[1] to be the first element.

    Why it fails

    Every array starts at index 0, which is its lower bound. The first valid index is not 1.

    Do this instead

    Read v[0] as the first element and v[5] as the last.

  • Common mistake

    Taking the array size as the last index

    What it looks like

    Believing char v[6]; makes v[6] a valid element.

    Why it fails

    Valid indices for size n run from 0 to n-1. Index 6 lies outside v.

    Do this instead

    Compute the last valid index as n-1, which is 5 for six elements.

  • Common mistake

    Treating a pointer as if it holds a value of its type

    What it looks like

    Reading char *p; as if p itself were a char.

    Why it fails

    The star means pointer to. The pointer variable holds the address of a char object, not the char itself.

    Do this instead

    Think of p as holding a location, and the char object as the thing it refers to.

  • Common mistake

    Reading the brackets and star as interchangeable symbols

Practice Reading Declarations

EASY

For the declaration int scores[5]; state the element count, the first valid index, and the last valid index. Then say whether a pointer declared as int *q; is an array or a pointer, and what type of object it is meant to refer to.

Hints
  • The number in the brackets gives the element count.
  • Valid indices run from 0 to n-1.
  • The star means pointer to, so q holds an address of an int object.

Key Takeaways

  • In a declaration, [ ] means array of and * means pointer to, so the symbol tells you what kind of thing the name is.
  • The declaration char v[6]; creates six char elements, indexed from v[0] to v[5].
  • Every array starts at index 0, so the valid indices for an array of size n run from 0 to n-1.
  • The declaration char *p; creates a pointer variable meant to hold the address of one object of type char, not the value itself.
  • The declared type tells you what kind of object a pointer is meant to refer to, so read the type alongside the symbol.

Related concepts

More concepts starting with U