Go language pointer

&Bracket asterisk principle: due to the conflict of the editor, (*) only represents an asterisk

&Null principle for pointers that do not point to addresses: if a pointer is declared but does not point to an address, the address of this pointer will be nil (null)

&Pointer first allocates address space principle: after declaring the pointer, a section of memory space must be allocated first before reading and writing the value of the pointer

&Pointers don't like the variable address principle: after declaring the pointer, use the statement p = new(int) to allocate a section of int memory space instead of pointing to the address of the variable p = & A

Pointer definition and initialization

Syntax: var pointer name (*) pointer type

package main

import "fmt"

func main() {

	// 1. Define pointer variables and variables of type int
	var p_int *int
	num1 := 100

	// 2. Make the pointer p_int point to the address of the variable num1
	p_int = &num1

	// 3. Modifying the value of the pointer essentially modifies the value it points to
	*p_int = 200
	fmt.Println(num1) // 200
}

Key point (i.e. null principle for pointers that do not point to addresses): pointers that do not point to variable addresses are null (nil)

package main

import "fmt"

func main() {

	var p_int *int
	fmt.Println(p_int) // <nil>

	num1 := 100
	p_int = &num1
	fmt.Println(p_int) // 0xc0000160d0
}

Wild pointer: the pointer points to an unknown space (that is, the pointer allocates address space first)

package main

func main() {

	// Wild pointer -- points to an unknown space
	var p_int *int

	//*p_int = 100 // invalid memory address or nil pointer dereference
}

Create memory space (that is, pointers don't like the variable principle)

package main

import "fmt"

func main() {

	var p_int *int

	p_int = new(int)

	*p_int = 100

	fmt.Println(*p_int) // 100
}

Automatic derivation type

package main

import "fmt"

func main() {

	// Automatic derivation type
	// 1. Address of assigned variable
	num := 100
	p := &num
	fmt.Println(*p) // 100

	// 2. Create address space
	p1 := new(int)
	*p1 = 200
	fmt.Println(*p1) // 200
}

Pointer as function parameter

Key points: address transfer

package main

import "fmt"

// Exchange the values of a and b
func Swap(a *int, b *int) {
	*a, *b = *b, *a
}

func main() {

	num1, num2 := 1, 2

	fmt.Println(num1, num2) // 1 2

	Swap(&num1, &num2)

	fmt.Println(num1, num2) // 2 1
}

Array pointer

Array pointer declaration and assignment process

Step: first initialize the array, then declare the array pointer, and finally point the pointer to the array

package main

import "fmt"

func main() {

	// 1. Define an array of length 3
	arr := [3]int{1, 2, 3}

	// 2. Define array pointer
	var p *[3]int

	// 3. Pointer to array
	p = &arr

	// 4. Print the value of the pointer
	fmt.Println(*p) // [1 2 3]
}

Array pointer initialization process (i.e. automatic derivation)

package main

import "fmt"

func main() {

	// 1. Define an array of length 3
	arr := [3]int{1, 2, 3}

	// 2. Pointer to array
	p := &arr

	// 3. Print the value of the pointer
	fmt.Println(*p) // [1 2 3]
}

Use of array pointers

Syntax: (*) array pointer name [index entry] = value OR array pointer name [index entry] = value

package main

import "fmt"

func main() {

	// 1. Define an array of length 3
	arr := [3]int{1, 2, 3}

	// 2. Pointer to array
	p := &arr

	// 3. Use array pointer
	(*p)[0] = 100
	p[1] = 200

	// 4. Print array pointer
	fmt.Println(*p) // [100 200 3]
}

Array pointer as function parameter

Key points: address transfer

package main

import "fmt"

func Test(p *[3]int) {
	p[1] = 100
}

func main() {

	arr := [3]int{1, 2, 3}

	fmt.Println(arr) // [1 2 3]

	Test(&arr)

	fmt.Println(arr) // [1 100 3]
}

Pointer array

simple form

package main

import "fmt"

func main() {

	num1, num2, num3 := 1, 2, 3

	var p [3]*int = [3]*int{&num1, &num2, &num3}

	fmt.Println(p) // [0xc0000ac058 0xc0000ac070 0xc0000ac078]

	fmt.Println(*p[0]) // 1
	fmt.Println(*p[1]) // 2
	fmt.Println(*p[2]) // 3
}

Complex form

package main

import "fmt"

func main() {

	arr1, arr2, arr3 := [3]int{1, 2, 3}, [3]int{4, 5, 6}, [3]int{7, 8, 9}

	var p [3]*[3]int = [3]*[3]int{&arr1, &arr2, &arr3}

	fmt.Println(p) // [0xc0000141c8 0xc0000141e0 0xc0000141f8]

	fmt.Println(*p[0]) // [1 2 3]
	fmt.Println(*p[1]) // [4 5 6]
	fmt.Println(*p[2]) // [7 8 9]
}

Slice pointer

Slice pointer initialization process (i.e. automatic derivation)

package main

import "fmt"

func main() {

	slice_p := &[]int{1, 2, 3}

	fmt.Println(*slice_p) // [1 2 3]

	*slice_p = append(*slice_p, 4, 5, 6)

	fmt.Println(*slice_p) // [1 2 3 4 5 6]
}

Slice pointer as function parameter

Key points: address transfer

package main

import "fmt"

func Test(p *[]int) {
	*p = append(*p, 4, 5, 6)
}

func main() {

	slice_p := &[]int{1, 2, 3}

	Test(slice_p)

	fmt.Println(*slice_p) // [1 2 3 4 5 6]
}

Structure pointer

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	// Automatic derivation
	struct_p := &Student{1, 100}

	fmt.Println(*struct_p) // {1 100}

	// Declaration and assignment
	var struct_p1 *Student = &Student{2, 90}

	fmt.Println(*struct_p1) // {2 90}
}

Use of structure pointer

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	// Declaration and assignment
	var struct_p1 *Student = &Student{2, 90}

	fmt.Println(*struct_p1) // {2 90}

	// Indirectly change the attributes in the structure through the pointer
	(*struct_p1).score = 1000
	// Directly change the attributes in the structure through the pointer
	struct_p1.id = 10

	fmt.Println(*struct_p1) // {10 1000}
}

Structure pointer as function parameter

Key points: address transfer

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func Test(struct_p *Student) {
	struct_p.score = 72
}

func main() {

	// Declaration and assignment
	var struct_p1 *Student = &Student{2, 90}

	fmt.Println(*struct_p1) // {2 90}

	Test(struct_p1)

	fmt.Println(*struct_p1) // {2 72}
}

Structure array pointer

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	struct_p := &[3]Student{
		{1, 100},
		{1, 100},
		{1, 100},
	}

	fmt.Println(*struct_p) // [{1 100} {1 100} {1 100}]

	struct_p[0].score = 1000

	fmt.Println(*struct_p) // [{1 1000} {1 100} {1 100}]
}

Structure pointer of map type

package main

import "fmt"

type Student struct {
	id    int
	score int
}

func main() {

	// The key of the dictionary is an integer
	// The value of the dictionary is an array pointer of structure type
	m := make(map[int]*[3]Student)

	m[1] = &[3]Student{
		{1, 100},
		{2, 200},
		{3, 300},
	}

	fmt.Println(*(m[1])) // [{1 100} {2 200} {3 300}]
}

Multistage pointer

package main

import "fmt"

func main() {

	// First level pointer -- points to the address of the variable
	num1 := 1
	p := &num1
	fmt.Println(*p) // 1

	// Secondary pointer -- the address of the primary pointer
	pp := &p
	fmt.Println(pp)   // 0xc00000d8028 -- address of secondary pointer
	fmt.Println(*pp)  // 0xc0000016098 -- address of first level pointer
	fmt.Println(**pp) // 1 -- the value pointed to by the first level pointer
}

Keywords: Java C Go Front-end

Added by joespenceley on Sat, 25 Sep 2021 14:35:02 +0300