Concepts / Array and Pointer Basics

Array and Pointer Basics

The prefix unary ampersand means address of. Applied to an object such as v[3], it produces that object's address, which a pointer can hold.

  • Programming

Predicting What a Pointer Leads To

A pointer is useful only if you can move in two directions: from an object to its address, and from a pointer back to the object it points to. This article is about those two moves. Each one is a prefix unary operator, meaning it sits directly in front of the single operand it acts on. The ampersand goes from an object to its address. The asterisk goes from a pointer to the object it points to.

What do you think happens?

Suppose v is an array and p holds the address of its fourth element, v[3]. What does the expression that applies the prefix asterisk to p produce?

  • The address of v[3]

  • The object that p points to, which is v[3] and its stored value

  • The pointer p itself

Reveal answer
Answer:

The object that p points to, which is v[3] and its stored value

The prefix asterisk means contents of. Applied to a pointer, it gives the object that the pointer points to. Here that object is the fourth element of v. Commit to your answer, because the next sections check your reasoning.

Getting an Address with the Ampersand

Definition

The prefix unary ampersand means address of. Applied to an object such as v[3], it produces that object's address, which a pointer can hold.

The result of the ampersand is an address, not the element's value. The address-of operator answers the question 'where is this object?' It does not answer 'what is stored in this object?' Keeping those two questions apart is the main skill this article builds.

In the source's example, applying the ampersand to v[3] yields the address of the fourth element of v. A pointer declaration such as the one below is read as 'p is initialized to the address of v[3]'. The declaration gives p a target. It does not copy the element anywhere.

c
Notes on the code
  • &v[3] produces the address of the fourth element of v
  • p receives that address as its value
  • The element v[3] is not copied or changed
v[0]first elementv[1]second elementv[2]third elementv[3]fourth element&v[3]a memory locationv[4]fifth elementaddress of
Where does &v[3] point in memory, and how do the slots v[0] through v[4] sit relative to one another? The ampersand names the location of one slot, and the pointer keeps that location.

Tracing an Address and Its Target

Now follow the operations one at a time. Start with the declaration that stores the address of v[3] in p. Then apply the prefix asterisk to p and watch what object each step refers to. The diagram below shows the path. The pointer p reaches the fourth element, and the value read through p is what gets copied into x.

v[3]the fourth elementppointer variablexreceives a value1. &v[3] gives the address; p stores it2. *p refers back to the object at that address3. the value read through p is assigned to x
After each step in p = &v[3] and then *p, which object is referred to, and what does that step produce?
Worked example

Following p = &v[3] and then reading through p

Given an array v and the statements below, state the object each expression refers to and what it produces.

  1. 1
    Step 1: evaluate &v[3]

    The ampersand is applied to the object v[3]. The result is the address of the fourth element. It is an address, so it is the right kind of value to store in a pointer.

  2. 2
    Step 2: store the address in p

    The declaration gives p the address of v[3] as its value. p now refers to v[3]. Nothing has been copied out of v[3] yet.

  3. 3
    Step 3: evaluate *p

    The asterisk is applied to the pointer p. The object p points to is v[3], so the expression refers to v[3] itself and gives access to the value stored there.

  4. 4
    Step 4: assign the value to x

    The value read through p is what x receives. p still holds the same address after this step, because reading through a pointer does not change the pointer or the object it refers to.

Result

The address-of step refers to v[3] and produces its address. The dereference step refers to v[3] again and produces its stored value, which x receives. p is unchanged.

Reading Through a Pointer

Definition

The prefix unary asterisk means contents of. Applied to a pointer such as p, it gives the object that the pointer points to.

Dereferencing is the step that moves from the pointer back to the value it leads to. In the source's initialization, a variable x is set from the object p points to. The source phrases it this way: the object that p points to is written as the prefix asterisk applied to p.

c
Notes on the code
  • *p applies the asterisk to the pointer p
  • The object p points to is v[3] in this lesson's setup
  • x is set from that object's value

Two Operators in One Expression

Both operators are prefix unary operators, and they point in opposite directions. The same written form can therefore mean very different things depending on what follows it. A useful check for any expression is to ask what kind of thing the operator acts on. An object goes into the ampersand and an address comes out. A pointer goes into the asterisk and an object comes out. If you apply an operator to the wrong kind of operand, the expression no longer means what you intended.

*dereference: object at theaddress&address-of: address of theobjectv[3]the fourth elementapplied firstapplied second
In *&v[3], which operator applies first, what does each operator produce, and why does the whole expression give back v[3]?

Reading *&v[3] from the inside out: the ampersand acts on v[3] and produces its address. The asterisk then acts on that address and gives back the object at that address, which is v[3]. The two operations undo each other, so the whole expression refers to v[3]. The inner operator applies first, which is why evaluating the expression from left to right on the page can mislead you.

OperatorWhat it acts onWhat it producesQuestion it answers
Prefix ampersand (address of)An object such as v[3]The address of that objectWhere is this object?
Prefix asterisk (contents of)A pointer such as pThe object the pointer points toWhat is stored in the object the pointer leads to?

The two prefix unary operators side by side

Mistakes Beginners Make with the Two Operators

  • Common mistake

    Reading the ampersand as if it returns the element's value

    What it looks like

    char *p = &v[3]; is read as 'p gets the value of v[3]'.

    Why it fails

    The ampersand produces an address. It answers where the object is, not what is stored in it.

    Do this instead

    Read the declaration as 'p is initialized to the address of v[3]'. The element itself is not copied.

  • Common mistake

    Assuming the asterisk changes the pointer

    What it looks like

    After char x = *p;, believing that p now points somewhere else.

    Why it fails

    Reading through a pointer does not change the pointer or the object it refers to.

    Do this instead

    After the read, p still holds the same address. Only the value of x changed.

  • Common mistake

    Applying the operators in the wrong order or to the wrong kind of operand

    What it looks like

    Treating *&v[3] as if the asterisk acted on v[3] before the ampersand did.

    Why it fails

    The inner operator applies first. The ampersand needs an object, and the asterisk needs a pointer.

    Do this instead

    Check the operand type at each step: the ampersand takes an object and gives an address, and the asterisk takes a pointer and gives an object.

  • Common mistake

    Confusing the output of a copy loop because the pointer and the object it refers to were mixed up

Why This Matters for Copying Array Elements

The source introduces these operations with a practical goal: copying ten elements from one array to another. Once a pointer can reach an element and that element's contents can be read through the pointer, the program can work on array elements through pointers instead of naming each element directly. The example below is an illustration of that idea and is not taken from the source.

c
Notes on the code
  • ps and pd each hold the address of one element
  • x receives the value read through ps
  • Writing through pd stores the value into dst[3]

Practice Tracing Pointer Operations

MEDIUM

Given an array v and the statements char *p = &v[3]; char x = *p; state, for each of these expressions, the object it refers to and what it produces: (a) &v[3], (b) p, (c) *p, (d) *&v[3].

Hints
  • For (a), the ampersand acts on an object and produces an address.
  • For (b), p is a pointer variable, and it holds an address.
  • For (c), the asterisk acts on the pointer p and gives the object p points to.
  • For (d), work from the inside out: the ampersand acts first, then the asterisk undoes it.

Key Takeaways

  • The prefix unary ampersand means address of. Applied to an object such as v[3], it produces that object's address, which a pointer can hold.
  • The prefix unary asterisk means contents of. Applied to a pointer such as p, it gives the object that the pointer points to.
  • Reading through a pointer does not change the pointer or the object it refers to, so p keeps pointing at the same place.
  • Check the operand type at each step: an object goes into the ampersand and an address comes out, and a pointer goes into the asterisk and an object comes out.
  • These two operations are the basis for working with individual array elements through pointers, including tasks such as copying elements from one array to another.

Related concepts

More concepts starting with A