Pointers

Go supports the use of pointers through the familiar C-style * notation. However, Go pointers are more restricted, e.g. pointer arithmetic is not allowed.

Getting the Address of a Variable

A pointer is a value that stores the address of some other variable. In Go, the & operator returns a variable’s address. For example:

var n int = 5

fmt.Println("           n: ", n)
fmt.Println("address of n: ", &n)  // & is the address-of operator

On my computer this code prints:

           n:  5
address of n:  0x182000c8

The address of a variable depends upon your computer and the programs that are currently in RAM, and so this number ususally varies from run to run.

Pointer Types

A pointer variable stores the address of a variable, e.g.:

var n int = 5
var p *int = &n   // *int is the type "pointer to int"

fmt.Println("n: ", n)
fmt.Println("p: ", p)

In general, for any type T, *T is the type “pointer to T”.

Type inference also works with pointers, so we could rewrite the above example like this:

n := 5
p := &n

fmt.Println("n: ", n)
fmt.Println("p: ", p)

The zero-value for a pointer is nil:

var p *int             // nil is the zero-value for a pointer
fmt.Println("p: ", p)

if p == nil {
        fmt.Println("p has the value nil")
}

Passing By Reference

An important use of pointers in Go is to simulate passing parameters by reference. For example, invert takes a pointer to a float64 as input, and replaces the number it points to with its reciprocal (so long as it is not 0):

func invert(p *float64) {
        if *p != 0.0 {
                *p = 1 / *p
        }
}

You call the invert function like this:

x := 3.0
invert(&x)  // note the use of &
fmt.Println("x: ", x)

If you forget the & and write invert(n), you’ll get a compiler error complaining about a type mis-match.

Questions

  1. Suppose x is a Go variable. What is its address?

  2. Consider the following code:

    s := "cat"
    p := &s
    q := &p
    

    What are the types of p and q?

  3. What is the zero-type for pointers?

  4. Consider the following code:

    x := 3
    fmt.Println(*&x)   // assume fmt has been imported
    

    Does it compile? If so, what does it print?

  5. Write a function called swap that exchanges the takes two int pointers as input and exchanges the values they point to.