Pointer Puzzles

Exercise: Pointer Puzzles

Difficulty - Beginner

Learning Objectives

  • Understand pointer basics and the & and * operators
  • Learn when to use pointers vs values
  • Practice pointer arithmetic alternatives in Go
  • Master nil pointer handling
  • Understand pointer receivers vs value receivers

Problem Statement

Create a pointers package that demonstrates various pointer operations and patterns in Go.

Function Signatures

 1package pointers
 2
 3// Swap swaps two integer values using pointers
 4func Swap(a, b *int)
 5
 6// Increment increments a value by n using a pointer
 7func Increment(val *int, n int)
 8
 9// ReverseSliceInPlace reverses a slice in place
10func ReverseSliceInPlace(slice *[]int)
11
12// Counter is a simple counter type
13type Counter struct {
14	count int
15}
16
17// NewCounter creates a new counter
18func NewCounter() *Counter
19
20// Inc increments the counter
21func Inc()
22
23// Value returns the current count
24func Value() int
25
26// Reset resets the counter to zero
27func Reset()
28
29// Person represents a person
30type Person struct {
31	Name string
32	Age  int
33}
34
35// UpdatePerson updates person fields through pointer
36func UpdatePerson(p *Person, name string, age int)
37
38// CopyPerson creates a copy of a person
39func CopyPerson(p Person) Person

Example Usage

 1package main
 2
 3import (
 4	"fmt"
 5	"pointers"
 6)
 7
 8func main() {
 9	// Swap example
10	x, y := 10, 20
11	fmt.Printf("Before swap: x=%d, y=%d\n", x, y)
12	pointers.Swap(&x, &y)
13	fmt.Printf("After swap: x=%d, y=%d\n", x, y)
14
15	// Increment example
16	val := 5
17	pointers.Increment(&val, 10)
18	fmt.Printf("After increment: %d\n", val) // 15
19
20	// Reverse slice
21	nums := []int{1, 2, 3, 4, 5}
22	pointers.ReverseSliceInPlace(&nums)
23	fmt.Println("Reversed:", nums) // [5, 4, 3, 2, 1]
24
25	// Counter example
26	counter := pointers.NewCounter()
27	counter.Inc()
28	counter.Inc()
29	counter.Inc()
30	fmt.Printf("Count: %d\n", counter.Value()) // 3
31	counter.Reset()
32	fmt.Printf("After reset: %d\n", counter.Value()) // 0
33
34	// Person example
35	person := pointers.Person{Name: "Alice", Age: 30}
36	pointers.UpdatePerson(&person, "Alice Smith", 31)
37	fmt.Printf("Updated: %+v\n", person)
38
39	// Copy person
40	copy := pointers.CopyPerson(person)
41	copy.Name = "Bob"
42	fmt.Printf("Original: %s, Copy: %s\n", person.Name, copy.Name)
43}

Solution

Click to see the complete solution
 1package pointers
 2
 3// Swap swaps two integer values using pointers
 4func Swap(a, b *int) {
 5	*a, *b = *b, *a
 6}
 7
 8// Increment increments a value by n using a pointer
 9func Increment(val *int, n int) {
10	*val += n
11}
12
13// ReverseSliceInPlace reverses a slice in place
14func ReverseSliceInPlace(slice *[]int) {
15	s := *slice
16	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
17		s[i], s[j] = s[j], s[i]
18	}
19}
20
21// Counter is a simple counter type
22type Counter struct {
23	count int
24}
25
26// NewCounter creates a new counter
27func NewCounter() *Counter {
28	return &Counter{count: 0}
29}
30
31// Inc increments the counter
32func Inc() {
33	c.count++
34}
35
36// Value returns the current count
37func Value() int {
38	return c.count
39}
40
41// Reset resets the counter to zero
42func Reset() {
43	c.count = 0
44}
45
46// Person represents a person
47type Person struct {
48	Name string
49	Age  int
50}
51
52// UpdatePerson updates person fields through pointer
53func UpdatePerson(p *Person, name string, age int) {
54	if p == nil {
55		return
56	}
57	p.Name = name
58	p.Age = age
59}
60
61// CopyPerson creates a copy of a person
62func CopyPerson(p Person) Person {
63	return Person{
64		Name: p.Name,
65		Age:  p.Age,
66	}
67}

Key Takeaways

  1. Pointers Enable Mutation: Use pointers to modify values in functions
  2. Nil Checks: Always check for nil pointers before dereferencing
  3. Receiver Choice: Use pointer receivers when you need to modify state
  4. Memory Efficiency: Pointers avoid copying large structs
  5. Clarity: Pointers make it explicit when a function can modify arguments