&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 }