This is the 10th day of my participation in the August More Text Challenge. For details, see:August is more challenging

The concept of Pointers

A pointer is a variable that stores the memory address of another variable. As we all know, variables are handy placeholders for referencing computer memory addresses.

Gets the address of the variable

The Go language has an ampersand (&) that returns the memory address of a variable when placed in front of it.

package main

import "fmt"

func main(a) {
   var a int = 90   

   fmt.Printf("Address of variable: %x\n", &a  )
}
Copy the code

Running result:

Address of variable:41568a310
Copy the code

Pointer to a statement

*T is the type of a pointer variable. It points to a value of type T.

var var_name *var-type
Copy the code

Var-type indicates the pointer type. Var_name indicates the name of the pointer variable. The asterisk (*) is used to specify that the variable is a pointer.

var ip *int        /* Points to an integer */
var fp *float32    /* Points to floating point */
Copy the code

Example code:

package main

import "fmt"

func main(a) {
   var a int= 90   /* Declare the actual variable */
   var ip *int        /* Declare a pointer variable */

   ip = &a  /* The storage address of the pointer variable */

   fmt.Printf("The address of the variable a is: %x\n", &a  )

   /* The storage address of the pointer variable */
   fmt.Printf("Storage address of the IP variable: %x\n", ip )

   /* Use Pointers to access values */
   fmt.Printf("* IP variable value: %d\n", *ip )
}
Copy the code

Running result:

The address of the variable a is:41568A310 storage address of the IP variable:41568A310 * IP variable value:90
Copy the code

Example code:

package main

import "fmt"

type name int8
type first struct {
    a int
    b bool
    name
}

func main(a) {
    a := new(first)
    a.a = 1
    a.name = 11
    fmt.Println(a.b, a.a, a.name)
}
Copy the code

Running result:

false 1 11
Copy the code

Uninitialized variables are automatically assigned initial values

package main

import "fmt"

type name int8
type first struct {
    a int
    b bool
    name
}

func main(a) {
    var a = first{1.false.2}
    var b *first = &a
    fmt.Println(a.b, a.a, a.name, &a, b.a, &b, (*b).a)
}
Copy the code

Running result:

false 1 2& {1 false 2} 1 0xc042068018 1
Copy the code

Gets the address of a pointer by prefixing an ampersand (&) to a pointer variable

Null pointer

Go null pointer When a pointer is defined without being assigned to any variable, it has the value nil. A nil pointer is also called a null pointer. Nil is conceptually the same as null, None, nil, and null in other languages in that it refers to a zero or null value. A pointer variable is usually abbreviated to PTR.

Null pointer judgment:

if(ptr ! =nil)     /* PTR is not null */
if(ptr == nil)    /* PTR is null */
Copy the code

Gets the value of the pointer

Getting a pointer means accessing the value of the variable to which the pointer points. The syntax is: *a

Example code:

package main  
import (  
    "fmt"
)

func main(a) {  
    b := 255
    a := &b
    fmt.Println("address of b is", a)
    fmt.Println("value of b is", *a)
}
Copy the code

Manipulating a pointer changes the value of a variable

Example code:

package main

import (  
    "fmt"
)

func main(a) {  
    b := 255
    a := &b
    fmt.Println("address of b is", a)
    fmt.Println("value of b is", *a)
    *a++
    fmt.Println("new value of b is", b)
}
Copy the code

The results

address of b is 0x1040a124  
value of b is 255  
new value of b is 256
Copy the code

Pointer to a pointer

If a pointer variable contains the address of another pointer variable, it is called a pointer variable to a pointer.

var ptr **int;
package main

import "fmt"

func main(a) {

   var a int
   var ptr *int
   var pptr **int

   a = 3000

   /* Pointer PTR address */
   ptr = &a

   /* Pointer to PTR address */
   pptr = &ptr

   /* Get the PPTR value */
   fmt.Printf("Variable a = %d\n", a )
   fmt.Printf("Pointer variable * PTR = %d\n", *ptr )
   fmt.Printf("Pointer variable to pointer ** PPTR = %d\n", **pptr)
}
Copy the code

Running result:

Variables a =3000Pointer variable * PTR =3000Pointer variable to pointer ** PPTR =3000
Copy the code

Function Pointers and pointer functions

Function pointer: a pointer variable to a function, which is essentially a pointer variable. Pointer function: Is essentially a function. A function return type is a pointer to a type.

import "fmt"
/* Function pointer: is a pointer variable to a function. Pointer function: Is essentially a function. A function return type is a pointer to a type. */
func main(a)  {

  //2. Function pointer
  a := 100
  fmt.Println("a,",a)
  b := a
  fmt.Println("b,",b)
  b = 200
  fmt.Println(a, b)
  fmt.Println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --")
  fmt.Printf("Function add type: %T\n", add) // Add: func(int, int) int
  fmt.Println(Print the add function:, add) // 0x1095bc0, the address of the function, can be understood as a special variable.
  fmt.Println("Result of function execution:", add(a, b))
  var f1 func(int.int) int = add
  fmt.Println("F1 execution result:", f1(a, b))

  fmt.Println("f1,",f1, ",add,",add) // f1, 0x1093bb0 ,add, 0x1093bb0

  /* Conclusion: When a function is declared, the function name itself is a pointer. You don't have to add *. Function and function assignment, belong to shallow copy, copy pointer, two Pointers to the same memory space. * /
  /* 1. Pointer function: */
   res1:= fun1()
   fmt.Printf("res1:%p,%v\n",res1,*res1) / / [1 3 5 7]
   res2 := fun1()
   fmt.Printf("res2:%p,%v\n",res2,*res2) / / [1 3 5 7]
   res1[0] = 100
   fmt.Println(*res1) / / [100 3 5 7]
   fmt.Println(*res2) / / [1 3 5 7]
   fmt.Println("-- -- -- -- -- -- -- -- -- -- -- --")}// 1. Define a function to sum two numbers
// The function type is func (int,int) int
func add(a, b int) int  {
  return a + b
}

//2. Define a pointer function
func fun1(a)* [4]int{
  var arr [4] int
  for i:=0; i<len(arr); i++{ arr[i] = i*2+1
  }
  fmt.Printf("Array address: %p, array contents: %v\n",&arr,arr) / / [1 3 5 7]
  return &arr
}
Copy the code

Running result:

a, 100
b, 100
100 200The type of ------------------ function add:func(int.int) intPrint the add function:0x1095f20The result of the function:300Result of f1 execution:300
f1, 0x1095f20 ,add, 0x1095f20Array address:0xc4200180e0, array contents: [1 3 5 7]
res1:0xc4200180e0[1 3 5 7[array address:0xc420018140, array contents: [1 3 5 7]
res2:0xc420018140[1 3 5 7]
[100 3 5 7]
[1 3 5 7] -- -- -- -- -- -- -- -- -- -- -- --Copy the code

Pointer arrays and array Pointers

package main

import "fmt"

func main(a)  {
    /* Array pointer and pointer array: Pointer array: first, it is an array. The elements of the array are Pointers. The number of bytes in the array is determined by the array itself. It's short for "array of Pointers." Array pointer: First it's a pointer, it points to an array. On 32-bit systems it's always 4 bytes. I don't know how many bytes it points to. It's short for "pointer to an array." * /
     //1. Normal array
    num:=[4] int{1000.2000.3000.4000}
    fmt.Println(num) / / [1, 2, 3, 4]

    //2. Pointer Array: an array of Pointers
    var p [4] *int // Define a pointer array
    fmt.Printf("%T\n", p) //[4]*int
    for i:=0; i<len(num); i++{ add := &num[i] fmt.Println(add) p[i] = add } fmt.Println(p)//[0xc4200160c0 0xc4200160c8 0xc4200160d0 0xc4200160d8]

    //3. Array pointer: a pointer to an array
    var p2 *[4] int
    fmt.Printf("%T\n", p2) //*[4]int
    p2 = &num
    fmt.Println(p2) / / & [1000, 2000, 3000, 4000]
    for i:=0; i<len(num); i++{ fmt.Println((*p2)[i]) }//var p3 *[4]float64
    //var p4 [4]*float64
    //var p5 *[4]*float64
    //var p6 ** [4]*int

}
Copy the code

Running result:

[1000 2000 3000 4000]
[4]*int
0xc420084020
0xc420084028
0xc420084030
0xc420084038
[0xc420084020 0xc420084028 0xc420084030 0xc420084038]
*[4]int
&[1000 2000 3000 4000]
1000
2000
3000
4000
Copy the code

Pass the arguments to the function using Pointers

The sample code

package main

import (  
    "fmt"
)

func change(val *int) {  
    *val = 55
}
func main(a) {  
    a := 58
    fmt.Println("value of a before function call is",a)
    b := &a
    change(b)
    fmt.Println("value of a after function call is", a)
}
Copy the code

The results

value of a before function call is 58  
value of a after function call is 55
Copy the code

Do not pass a pointer to an array to a function. Please use slices.

Suppose we want to make some changes to the array in the function, and the changes are made to the array in the function that the caller can see. One way is to pass a pointer to an array to the function.

package main

import (  
    "fmt"
)

func modify(arr *[3]int) {  
    (*arr)[0] = 90
}

func main(a) {  
    a := [3]int{89.90.91}
    modify(&a)
    fmt.Println(a)
}
Copy the code

The results

[90, 90, 91]Copy the code

Example code:

package main

import (  
    "fmt"
)

func modify(arr *[3]int) {  
    arr[0] = 90
}

func main(a) {  
    a := [3]int{89.90.91}
    modify(&a)
    fmt.Println(a)
}
Copy the code

The results

[90, 90, 91]Copy the code

While passing a pointer to an array as an argument to a function and modifying it, this is not the usual way to achieve this goal. We have slices.

Example code:

package main

import (  
    "fmt"
)

func modify(sls []int) {  
    sls[0] = 90
}

func main(a) {  
    a := [3]int{89.90.91}
    modify(a[:])
    fmt.Println(a)
}
Copy the code

Running result:

[90, 90, 91]Copy the code

Go does not support the pointer algorithm.

package main

func main() { b := […] int{109, 110, 111} p := &b p++ }

nvalid operation: p++ (non-numeric type *[3]int)

Pointer to an array

package main

import "fmt"

const MAX int = 3

func main(a) {

   a := []int{10.100.200}
   var i int

   for i = 0; i < MAX; i++ {
      fmt.Printf("a[%d] = %d\n", I, a[I])}}0] = 10
a[1] = 100
a[2] = 200
Copy the code

In one case, we might want to save the array, so we need to use the pointer.

package main

import "fmt"

const MAX int = 3

func main(a) {
   a := []int{10.100.200}
   var i int
   var ptr [MAX]*int;

   for  i = 0; i < MAX; i++ {
      ptr[i] = &a[i] /* Integer address assigned to pointer array */
   }

   for  i = 0; i < MAX; i++ {
      fmt.Printf("a[%d] = %d\n", I,* PTR [I])}}0] = 10
a[1] = 100
a[2] = 200
Copy the code

The pointer is used as a function argument

package main

import "fmt"

func main(a) {
   /* Define local variables */
   var a int = 100
   var b int= 200

   fmt.Printf("Value of a before exchange: %d\n", a )
   fmt.Printf("Value of b before exchange: %d\n", b )

   /* Call functions to exchange values * &a refers to the address of a variable * &b refers to the address of b variable */
   swap(&a, &b);

   fmt.Printf("Value of a after exchange: %d\n", a )
   fmt.Printf("Value of b after exchange: %d\n", b )
}

func swap(x *int, y *int) {
   var temp int
   temp = *x    /* Save the value of the x address */
   *x = *y      /* Assign y to x */
   *y = temp    /* Assign temp to y */
}
Copy the code

Running result:

The value of a before the exchange:100The value of b before the exchange:200The value of a after the exchange:200The value of b after swap:100
Copy the code